Skip to content

Commit

Permalink
feat(stats): add info about Jibri sessions
Browse files Browse the repository at this point in the history
Adds the following to the JSON stats:

"live_streaming_active" - active Jibri live streaming sessions
"recording_active" - active Jibri recording sessions
"sip_call_active" - active Jibri SIP calls
"live_streaming_pending" - pending live streaming Jibri sessions
"recording_pending" - pending recording Jibri sessions
"sip_call_pending" - pending SIP call Jibri sessions
  • Loading branch information
paweldomas committed Apr 16, 2020
1 parent 039cfe3 commit 33dfd2f
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 8 deletions.
7 changes: 7 additions & 0 deletions src/main/java/org/jitsi/jicofo/JitsiMeetConference.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import net.java.sip.communicator.service.protocol.*;
import org.jitsi.jicofo.bridge.*;
import org.jitsi.jicofo.recording.jibri.*;
import org.jitsi.protocol.xmpp.*;
import org.jitsi.utils.logging.*;
import org.jxmpp.jid.*;
Expand Down Expand Up @@ -87,6 +88,12 @@ public interface JitsiMeetConference
*/
void setStartMuted(boolean[] startMuted);

/**
* @return a stats snapshot for all {@link JibriSession}s used in this
* conference.
*/
JibriSessionStats getJibriSessionStats();

/**
* Gets the role of a member in the conference.
* @param jid the member whose role is to be determined.
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/org/jitsi/jicofo/JitsiMeetConferenceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3118,6 +3118,27 @@ protected FocusManager getFocusManager()
return ServiceUtils.getService(FocusBundleActivator.bundleContext, FocusManager.class);
}

/**
* {@inheritDoc}
*/
@Override
public JibriSessionStats getJibriSessionStats()
{
List<JibriSession> sessions = new ArrayList<>();

if (jibriRecorder != null)
{
sessions.addAll(jibriRecorder.getJibriSessions());
}

if (jibriSipGateway != null)
{
sessions.addAll(jibriSipGateway.getJibriSessions());
}

return new JibriSessionStats(sessions);
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ public abstract class CommonJibriStuff
*/
protected abstract JibriSession getJibriSessionForMeetIq(JibriIq iq);

/**
* @return a list with all {@link JibriSession}s used by this instance.
*/
public abstract List<JibriSession> getJibriSessions();

/**
* This method will be called when start IQ arrives from Jitsi Meet
* participant and {@link #getJibriSessionForMeetIq(JibriIq)} returns
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/org/jitsi/jicofo/recording/jibri/JibriRecorder.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.jivesoftware.smack.packet.*;
import org.osgi.framework.*;

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

import static org.jitsi.jicofo.recording.jibri.JibriSession.StartException;
Expand Down Expand Up @@ -120,6 +121,22 @@ protected JibriSession getJibriSessionForMeetIq(JibriIq iq)
return jibriSession;
}

/**
* {@inheritDoc}
*/
@Override
public List<JibriSession> getJibriSessions()
{
List<JibriSession> sessions = new ArrayList<>(1);

if (jibriSession != null)
{
sessions.add(jibriSession);
}

return sessions;
}

/**
* Starts new session for given iq. It is assumed that
* {@link CommonJibriStuff} has checked that there is no recording session
Expand Down
41 changes: 33 additions & 8 deletions src/main/java/org/jitsi/jicofo/recording/jibri/JibriSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,24 +276,49 @@ private void dispatchSessionStateChanged(
*/
private void emitSessionFailedEvent()
{
JibriSessionEvent.Type jibriType;
eventAdminProvider
.get()
.postEvent(
JibriSessionEvent.newFailedToStartEvent(
getJibriType()));
}

/**
* @return The {@link JibriSessionEvent.Type} of this session.
*/
public JibriSessionEvent.Type getJibriType()
{
if (isSIP)
{
jibriType = JibriSessionEvent.Type.SIP_CALL;
return JibriSessionEvent.Type.SIP_CALL;
}
else if (StringUtils.isNullOrEmpty(streamID))
{
jibriType = JibriSessionEvent.Type.RECORDING;
return JibriSessionEvent.Type.RECORDING;
}
else
{
jibriType = JibriSessionEvent.Type.LIVE_STREAMING;
return JibriSessionEvent.Type.LIVE_STREAMING;
}
}

eventAdminProvider
.get()
.postEvent(
JibriSessionEvent.newFailedToStartEvent(jibriType));
/**
* @return {@code true} if this sessions is active or {@code false}
* otherwise.
*/
public boolean isActive()
{
return Status.ON.equals(jibriStatus);
}

/**
* @return {@code true} if this session is pending or {@code false}
* otherwise.
*/
public boolean isPending()
{
return Status.UNDEFINED.equals(jibriStatus)
|| Status.PENDING.equals(jibriStatus);
}

/**
Expand Down
168 changes: 168 additions & 0 deletions src/main/java/org/jitsi/jicofo/recording/jibri/JibriSessionStats.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package org.jitsi.jicofo.recording.jibri;

import org.json.simple.*;

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

/**
* Statistics snapshot for {@link JibriSession}.
*/
public class JibriSessionStats
{
/**
* Counts active {@link JibriSession}s.
* @param sessions the list of sessions.
* @param jibriType the type of Jibri to count.
* @return how many active Jibri sessions of given type are in the list.
*/
private static int countActive(List<JibriSession> sessions,
JibriSessionEvent.Type jibriType)
{
return countJibris(sessions, jibriType, JibriSession::isActive);
}

/**
* Counts Jibri sessions.
* @param sessions the list of sessions to scan.
* @param jibriType the type of jibri session to be count.
* @param selector the selector which makes the decision on whether or not
* to count the given instance.
* @return the count of Jibri sessions of given type that pass
* the selector's test.
*/
private static int countJibris(
List<JibriSession> sessions,
JibriSessionEvent.Type jibriType,
Function<JibriSession, Boolean> selector)
{
int count = 0;

for (JibriSession session : sessions)
{
if (session.getJibriType().equals(jibriType)
&& selector.apply(session))
{
count++;
}
}

return count;
}

/**
* Counts pending Jibri sessions of given type.
* @param sessions the list of sessions to scan.
* @param jibriType the type of Jibri session to count.
* @return how many Jibri sessions of given type and in the pending state
* are there on the list.
*/
private static int countPending(List<JibriSession> sessions,
JibriSessionEvent.Type jibriType)
{
return countJibris(sessions, jibriType, JibriSession::isPending);
}

/**
* How many active recording Jibri sessions.
*/
private int activeRecordingSessions;

/**
* How many active lice streaming Jibri sessions.
*/
private int activeLiveStreamingSessions;

/**
* How many active SIP call Jibri sessions.
*/
private int activeSipCallSessions;

/**
* How many pending recording Jibri sessions.
*/
private int pendingRecordingSessions;

/**
* How many pending live streaming Jibri sessions
*/
private int pendingLiveStreamingSessions;

/**
* How many pending SIP call Jibri sessions.
*/
private int pendingSipCallSessions;

/**
* Creates empty instance initialized with 0 stats.
*/
public JibriSessionStats()
{

}

/**
* Creates new {@link JibriSessionStats} computed for the given list of
* {@link JibriSession}.
*
* @param sessions the list for which the stats will be generated.
*/
public JibriSessionStats(List<JibriSession> sessions)
{
activeLiveStreamingSessions
= countActive(
sessions,
JibriSessionEvent.Type.LIVE_STREAMING);
activeRecordingSessions
= countActive(
sessions,
JibriSessionEvent.Type.RECORDING);
activeSipCallSessions
= countActive(
sessions,
JibriSessionEvent.Type.SIP_CALL);

pendingLiveStreamingSessions
= countPending(
sessions,
JibriSessionEvent.Type.LIVE_STREAMING);
pendingRecordingSessions
= countPending(
sessions,
JibriSessionEvent.Type.RECORDING);
pendingSipCallSessions
= countPending(
sessions,
JibriSessionEvent.Type.SIP_CALL);
}

/**
* Merges statistics stored in the given instance with this instance's
* state by adding up values.
* @param stats the other stats to merge.
*/
public void merge(JibriSessionStats stats)
{
this.activeLiveStreamingSessions += stats.activeLiveStreamingSessions;
this.activeRecordingSessions += stats.activeRecordingSessions;
this.activeSipCallSessions += stats.activeSipCallSessions;
this.pendingLiveStreamingSessions += stats.pendingLiveStreamingSessions;
this.pendingRecordingSessions += stats.pendingRecordingSessions;
this.pendingSipCallSessions += stats.pendingSipCallSessions;
}

/**
* Describes as JSON.
* @param stats the JSON object where the stats will end up.
*/
public void toJSON(JSONObject stats)
{
stats.put("live_streaming_active", activeLiveStreamingSessions);
stats.put("recording_active", activeRecordingSessions);
stats.put("sip_call_active", activeSipCallSessions);

stats.put("live_streaming_pending", pendingLiveStreamingSessions);
stats.put("recording_pending", pendingRecordingSessions);
stats.put("sip_call_pending", pendingSipCallSessions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,19 @@ protected JibriSession getJibriSessionForMeetIq(JibriIq iq)
return sipSessions.get(sipAddress);
}

/**
* {@inheritDoc}
*/
@Override
public List<JibriSession> getJibriSessions()
{
List<JibriSession> sessions = new ArrayList<>(sipSessions.size());

sessions.addAll(sipSessions.values());

return sessions;
}

@Override
protected IQ handleStartRequest(JibriIq iq)
{
Expand Down
Loading

0 comments on commit 33dfd2f

Please sign in to comment.