Skip to content

Commit

Permalink
feat: Add a debug HTTP interface. (#860)
Browse files Browse the repository at this point in the history
* feat: Add a debug HTTP interface.
  • Loading branch information
bgrozev authored Jan 10, 2022
1 parent c81ec67 commit 2248f7c
Show file tree
Hide file tree
Showing 25 changed files with 415 additions and 3 deletions.
24 changes: 24 additions & 0 deletions src/main/java/org/jitsi/impl/protocol/xmpp/ChatMemberImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
*/
package org.jitsi.impl.protocol.xmpp;

import org.jetbrains.annotations.*;
import org.jitsi.jicofo.xmpp.*;
import org.jitsi.jicofo.xmpp.muc.*;
import org.jitsi.utils.*;
import org.jitsi.utils.logging2.*;
import org.jitsi.xmpp.extensions.jitsimeet.*;

Expand All @@ -43,6 +45,7 @@ public class ChatMemberImpl
/**
* The resource part of this {@link ChatMemberImpl}'s JID in the MUC.
*/
@NotNull
private final Resourcepart resourcepart;

/**
Expand All @@ -65,6 +68,7 @@ public class ChatMemberImpl
* Full MUC address:
* [email protected]/nickname
*/
@NotNull
private final EntityFullJid occupantJid;

/**
Expand Down Expand Up @@ -368,4 +372,24 @@ public String toString()
{
return String.format("ChatMember[%s, jid: %s]@%s", occupantJid, jid, hashCode());
}

@NotNull
public OrderedJsonObject getDebugState()
{
OrderedJsonObject o = new OrderedJsonObject();
o.put("resourcepart", resourcepart.toString());
o.put("region", String.valueOf(region));
o.put("join_order_number", joinOrderNumber);
o.put("occupant_jid", occupantJid.toString());
o.put("jid", String.valueOf(jid));
o.put("robot", robot);
o.put("is_jibri", isJibri);
o.put("is_jigasi", isJigasi);
o.put("role", String.valueOf(role));
o.put("stats_id", String.valueOf(statsId));
o.put("is_audio_muted", isAudioMuted);
o.put("is_video_muted", isVideoMuted);

return o;
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/jitsi/impl/protocol/xmpp/ChatRoom.java
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,7 @@ void join()
* @return The main room JID as a string.
*/
String getMainRoom();

@NotNull
OrderedJsonObject getDebugState();
}
25 changes: 24 additions & 1 deletion src/main/java/org/jitsi/impl/protocol/xmpp/ChatRoomImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import org.jxmpp.stringprep.*;

import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;

/**
Expand All @@ -64,6 +63,7 @@ public class ChatRoomImpl
/**
* The room JID (e.g. "room@service").
*/
@NotNull
private final EntityBareJid roomJid;

/**
Expand Down Expand Up @@ -929,6 +929,29 @@ public boolean isMemberAllowedToUnmute(Jid jid, MediaType mediaType)
return whitelist != null && whitelist.contains(jid.toString());
}

@Override
@NotNull
public OrderedJsonObject getDebugState()
{
OrderedJsonObject o = new OrderedJsonObject();
o.put("room_jid", roomJid.toString());
o.put("my_occupant_jid", String.valueOf(myOccupantJid));
OrderedJsonObject membersJson = new OrderedJsonObject();
for (ChatMemberImpl m : members.values())
{
membersJson.put(m.getJid(), m.getDebugState());
}
o.put("members", membersJson);
o.put("role", String.valueOf(role));
o.put("meeting_id", String.valueOf(meetingId));
o.put("is_breakout_room", isBreakoutRoom);
o.put("main_room", String.valueOf(mainRoom));
o.put("num_audio_senders", numAudioSenders);
o.put("num_video_senders", numVideoSenders);

return o;
}

class MemberListener implements ParticipantStatusListener
{
@Override
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/org/jitsi/jicofo/FocusManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.jitsi.jicofo.conference.*;
import org.jitsi.jicofo.jibri.*;
import org.jitsi.jicofo.stats.*;
import org.jitsi.utils.*;
import org.jitsi.utils.logging2.*;
import org.jitsi.utils.logging2.Logger;
import org.jitsi.utils.queue.*;
Expand Down Expand Up @@ -531,6 +532,24 @@ public boolean isJicofoIdConfigured()
return octoId != 0;
}

@NotNull
OrderedJsonObject getDebugState(boolean full)
{
OrderedJsonObject o = new OrderedJsonObject();
for (JitsiMeetConference conference : getConferences())
{
if (full)
{
o.put(conference.getRoomName().toString(), conference.getDebugState());
}
else
{
o.put(conference.getRoomName().toString(), conference.getParticipantCount());
}

}
return o;
}
/**
* Takes care of stopping {@link JitsiMeetConference} if no participant ever joins.
*
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/jitsi/jicofo/JitsiMeetConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
package org.jitsi.jicofo;

import org.jetbrains.annotations.*;
import org.jitsi.utils.*;
import org.jitsi.utils.logging2.*;

import java.util.*;
Expand Down Expand Up @@ -202,4 +204,20 @@ public int getOpusMaxAverageBitrate()
Integer maxAvgBitrate = getInt(PNAME_OPUS_MAX_AVG_BITRATE);
return maxAvgBitrate == null ? -1 : maxAvgBitrate;
}

@NotNull
public OrderedJsonObject getDebugState()
{
OrderedJsonObject o = new OrderedJsonObject();
o.put("start_audio_muted", String.valueOf(getStartAudioMuted()));
o.put("start_video_muted", String.valueOf(getStartVideoMuted()));
o.put("rtcstats_enabled", getRtcStatsEnabled());
o.put("callstats_enabled", getCallStatsEnabled());
o.put("min_bitrate", getMinBitrate());
o.put("start_bitrate", getStartBitrate());
o.put("stereo_enabled", stereoEnabled());
o.put("opus_max_average_bitrate", getOpusMaxAverageBitrate());

return o;
}
}
17 changes: 17 additions & 0 deletions src/main/java/org/jitsi/jicofo/bridge/Bridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import edu.umd.cs.findbugs.annotations.*;
import org.jitsi.jicofo.xmpp.*;
import org.jitsi.utils.*;
import org.jitsi.utils.stats.*;
import org.jitsi.xmpp.extensions.colibri.*;
import org.jxmpp.jid.*;
Expand Down Expand Up @@ -387,4 +388,20 @@ public boolean isInGracefulShutdown()
{
return shutdownInProgress;
}

@NonNull
public OrderedJsonObject getDebugState()
{
OrderedJsonObject o = new OrderedJsonObject();
o.put("version", String.valueOf(version));
o.put("stress", getStress());
o.put("operational", isOperational());
o.put("packet_rate", lastReportedPacketRatePps);
o.put("region", String.valueOf(region));
o.put("graceful-shutdown", isInGracefulShutdown());
o.put("overloaded", isOverloaded());
o.put("relay-id", String.valueOf(relayId));

return o;
}
}
15 changes: 15 additions & 0 deletions src/main/java/org/jitsi/jicofo/bridge/BridgeSelector.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.jetbrains.annotations.*;
import org.jitsi.jicofo.*;
import org.jitsi.jicofo.conference.*;
import org.jitsi.utils.*;
import org.jitsi.utils.concurrent.*;
import org.jitsi.utils.event.*;
import org.jitsi.xmpp.extensions.colibri.*;
Expand Down Expand Up @@ -350,6 +351,20 @@ public void removeHandler(EventHandler eventHandler)
eventEmitter.removeHandler(eventHandler);
}

@NotNull
public OrderedJsonObject getDebugState()
{
OrderedJsonObject o = new OrderedJsonObject();
o.put("strategy", bridgeSelectionStrategy.getClass().getSimpleName());
OrderedJsonObject bridgesJson = new OrderedJsonObject();
for (Bridge b : bridges.values())
{
bridgesJson.put(b.getJid().toString(), b.getDebugState());
}
o.put("bridges", bridgesJson);
return o;
}

public interface EventHandler
{
void bridgeRemoved(Bridge bridge);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.jitsi.jicofo.xmpp.muc.*;
import org.jitsi.utils.*;
import org.jitsi.xmpp.extensions.jibri.*;
import org.json.simple.*;
import org.jxmpp.jid.*;

import java.util.*;
Expand Down Expand Up @@ -126,4 +127,7 @@ MuteResult handleMuteRequest(
Jid toBeMutedJid,
boolean doMute,
MediaType mediaType);

@NotNull
OrderedJsonObject getDebugState();
}
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,48 @@ else if (!participant.hasModeratorRights()
return colibriSessionManager.mute(participant, doMute, mediaType) ? MuteResult.SUCCESS : MuteResult.ERROR;
}

@Override
@NotNull
public OrderedJsonObject getDebugState()
{
OrderedJsonObject o = new OrderedJsonObject();
o.put("name", roomName.toString());
o.put("config", config.getDebugState());
ChatRoom chatRoom = this.chatRoom;
o.put("chat_room", chatRoom == null ? "null" : chatRoom.getDebugState());
OrderedJsonObject participantsJson = new OrderedJsonObject();
for (Participant participant : participants)
{
participantsJson.put(participant.getEndpointId(), participant.getDebugState());
}
o.put("participants", participantsJson);
//o.put("jibri_recorder", jibriRecorder.getDebugState());
//o.put("jibri_sip_gateway", jibriSipGateway.getDebugState());
//o.put("transcriber_manager", transcriberManager.getDebugState());
ChatRoomRoleManager chatRoomRoleManager = this.chatRoomRoleManager;
o.put("chat_room_role_manager", chatRoomRoleManager == null ? "null" : chatRoomRoleManager.getDebugState());
o.put("started", started.get());
o.put("creation_time", creationTime.toString());
o.put("has_had_at_least_one_participant", hasHadAtLeastOneParticipant);
o.put("start_audio_muted", startAudioMuted);
o.put("start_video_muted", startVideoMuted);
o.put("colibri_session_manager", colibriSessionManager.getDebugState());
OrderedJsonObject conferencePropertiesJson = new OrderedJsonObject();
for (ConferenceProperties.ConferenceProperty conferenceProperty : conferenceProperties.getProperties())
{
conferencePropertiesJson.put(conferenceProperty.getKey(), conferenceProperty.getValue());
}
o.put("conference_properties", conferencePropertiesJson);
o.put("include_in_statistics", includeInStatistics);
o.put("conference_sources", conferenceSources.toJson());
o.put("audio_limit_reached", audioLimitReached);
o.put("video_limit_reached", videoLimitReached);
o.put("gid", gid);


return o;
}

/**
* Mutes all participants (except jibri or jigasi without "audioMute" support). Will block for colibri responses.
*/
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/jitsi/jicofo/conference/Participant.java
Original file line number Diff line number Diff line change
Expand Up @@ -607,4 +607,15 @@ public String toString()
return "Participant[" + getMucJid() + "]@" + hashCode();
}

@NotNull
public OrderedJsonObject getDebugState()
{
OrderedJsonObject o = new OrderedJsonObject();
o.put("id", getEndpointId());
o.put("remote_sources_queue", remoteSourcesQueue.getDebugState());
o.put("invite_runnable", inviteRunnable != null ? "Running" : "Not running");
//o.put("room_member", roomMember.getDebugState());
o.put("jingle_session", jingleSession == null ? "null" : "not null");
return o;
}
}
73 changes: 73 additions & 0 deletions src/main/java/org/jitsi/jicofo/rest/Debug.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright @ 2018 - present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.jicofo.rest;

import org.jetbrains.annotations.*;
import org.jitsi.jicofo.*;
import org.jitsi.jicofo.conference.*;
import org.jitsi.utils.*;
import org.json.simple.*;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.*;

/**
* An interface which exposes detailed internal state for the purpose of debugging.
*/
@Path("/debug")
public class Debug
{
@NotNull
private final JicofoServices jicofoServices
= Objects.requireNonNull(JicofoServices.jicofoServicesSingleton, "jicofoServices");

/**
* Returns json string with statistics.
* @return json string with statistics.
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@NotNull
public String getDebug(@DefaultValue("false") @QueryParam("full") boolean full)
{
return jicofoServices.getDebugState(full).toJSONString();
}

@GET
@Path("conference/{confId}")
@Produces(MediaType.APPLICATION_JSON)
@NotNull
public String confDebug(@PathParam("confId") String confId)
{
OrderedJsonObject confJson = jicofoServices.getConferenceDebugState(confId);
return confJson.toJSONString();
}

@GET
@Path("/conferences")
@Produces(MediaType.APPLICATION_JSON)
@NotNull
public String conferences(@PathParam("confId") String confId)
{
JSONArray conferencesJson = new JSONArray();
for (JitsiMeetConference c : jicofoServices.getFocusManager().getAllConferences())
{
conferencesJson.add(c.getRoomName().toString());
}
return conferencesJson.toJSONString();
}
}
Loading

0 comments on commit 2248f7c

Please sign in to comment.