Skip to content

Commit 33dfd2f

Browse files
committed
feat(stats): add info about Jibri sessions
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
1 parent 039cfe3 commit 33dfd2f

File tree

9 files changed

+318
-8
lines changed

9 files changed

+318
-8
lines changed

src/main/java/org/jitsi/jicofo/JitsiMeetConference.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import net.java.sip.communicator.service.protocol.*;
2121
import org.jitsi.jicofo.bridge.*;
22+
import org.jitsi.jicofo.recording.jibri.*;
2223
import org.jitsi.protocol.xmpp.*;
2324
import org.jitsi.utils.logging.*;
2425
import org.jxmpp.jid.*;
@@ -87,6 +88,12 @@ public interface JitsiMeetConference
8788
*/
8889
void setStartMuted(boolean[] startMuted);
8990

91+
/**
92+
* @return a stats snapshot for all {@link JibriSession}s used in this
93+
* conference.
94+
*/
95+
JibriSessionStats getJibriSessionStats();
96+
9097
/**
9198
* Gets the role of a member in the conference.
9299
* @param jid the member whose role is to be determined.

src/main/java/org/jitsi/jicofo/JitsiMeetConferenceImpl.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3118,6 +3118,27 @@ protected FocusManager getFocusManager()
31183118
return ServiceUtils.getService(FocusBundleActivator.bundleContext, FocusManager.class);
31193119
}
31203120

3121+
/**
3122+
* {@inheritDoc}
3123+
*/
3124+
@Override
3125+
public JibriSessionStats getJibriSessionStats()
3126+
{
3127+
List<JibriSession> sessions = new ArrayList<>();
3128+
3129+
if (jibriRecorder != null)
3130+
{
3131+
sessions.addAll(jibriRecorder.getJibriSessions());
3132+
}
3133+
3134+
if (jibriSipGateway != null)
3135+
{
3136+
sessions.addAll(jibriSipGateway.getJibriSessions());
3137+
}
3138+
3139+
return new JibriSessionStats(sessions);
3140+
}
3141+
31213142
/**
31223143
* {@inheritDoc}
31233144
*/

src/main/java/org/jitsi/jicofo/recording/jibri/CommonJibriStuff.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ public abstract class CommonJibriStuff
156156
*/
157157
protected abstract JibriSession getJibriSessionForMeetIq(JibriIq iq);
158158

159+
/**
160+
* @return a list with all {@link JibriSession}s used by this instance.
161+
*/
162+
public abstract List<JibriSession> getJibriSessions();
163+
159164
/**
160165
* This method will be called when start IQ arrives from Jitsi Meet
161166
* participant and {@link #getJibriSessionForMeetIq(JibriIq)} returns

src/main/java/org/jitsi/jicofo/recording/jibri/JibriRecorder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.jivesoftware.smack.packet.*;
2828
import org.osgi.framework.*;
2929

30+
import java.util.*;
3031
import java.util.concurrent.*;
3132

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

124+
/**
125+
* {@inheritDoc}
126+
*/
127+
@Override
128+
public List<JibriSession> getJibriSessions()
129+
{
130+
List<JibriSession> sessions = new ArrayList<>(1);
131+
132+
if (jibriSession != null)
133+
{
134+
sessions.add(jibriSession);
135+
}
136+
137+
return sessions;
138+
}
139+
123140
/**
124141
* Starts new session for given iq. It is assumed that
125142
* {@link CommonJibriStuff} has checked that there is no recording session

src/main/java/org/jitsi/jicofo/recording/jibri/JibriSession.java

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,24 +276,49 @@ private void dispatchSessionStateChanged(
276276
*/
277277
private void emitSessionFailedEvent()
278278
{
279-
JibriSessionEvent.Type jibriType;
279+
eventAdminProvider
280+
.get()
281+
.postEvent(
282+
JibriSessionEvent.newFailedToStartEvent(
283+
getJibriType()));
284+
}
285+
286+
/**
287+
* @return The {@link JibriSessionEvent.Type} of this session.
288+
*/
289+
public JibriSessionEvent.Type getJibriType()
290+
{
280291
if (isSIP)
281292
{
282-
jibriType = JibriSessionEvent.Type.SIP_CALL;
293+
return JibriSessionEvent.Type.SIP_CALL;
283294
}
284295
else if (StringUtils.isNullOrEmpty(streamID))
285296
{
286-
jibriType = JibriSessionEvent.Type.RECORDING;
297+
return JibriSessionEvent.Type.RECORDING;
287298
}
288299
else
289300
{
290-
jibriType = JibriSessionEvent.Type.LIVE_STREAMING;
301+
return JibriSessionEvent.Type.LIVE_STREAMING;
291302
}
303+
}
292304

293-
eventAdminProvider
294-
.get()
295-
.postEvent(
296-
JibriSessionEvent.newFailedToStartEvent(jibriType));
305+
/**
306+
* @return {@code true} if this sessions is active or {@code false}
307+
* otherwise.
308+
*/
309+
public boolean isActive()
310+
{
311+
return Status.ON.equals(jibriStatus);
312+
}
313+
314+
/**
315+
* @return {@code true} if this session is pending or {@code false}
316+
* otherwise.
317+
*/
318+
public boolean isPending()
319+
{
320+
return Status.UNDEFINED.equals(jibriStatus)
321+
|| Status.PENDING.equals(jibriStatus);
297322
}
298323

299324
/**
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package org.jitsi.jicofo.recording.jibri;
2+
3+
import org.json.simple.*;
4+
5+
import java.util.*;
6+
import java.util.function.*;
7+
8+
/**
9+
* Statistics snapshot for {@link JibriSession}.
10+
*/
11+
public class JibriSessionStats
12+
{
13+
/**
14+
* Counts active {@link JibriSession}s.
15+
* @param sessions the list of sessions.
16+
* @param jibriType the type of Jibri to count.
17+
* @return how many active Jibri sessions of given type are in the list.
18+
*/
19+
private static int countActive(List<JibriSession> sessions,
20+
JibriSessionEvent.Type jibriType)
21+
{
22+
return countJibris(sessions, jibriType, JibriSession::isActive);
23+
}
24+
25+
/**
26+
* Counts Jibri sessions.
27+
* @param sessions the list of sessions to scan.
28+
* @param jibriType the type of jibri session to be count.
29+
* @param selector the selector which makes the decision on whether or not
30+
* to count the given instance.
31+
* @return the count of Jibri sessions of given type that pass
32+
* the selector's test.
33+
*/
34+
private static int countJibris(
35+
List<JibriSession> sessions,
36+
JibriSessionEvent.Type jibriType,
37+
Function<JibriSession, Boolean> selector)
38+
{
39+
int count = 0;
40+
41+
for (JibriSession session : sessions)
42+
{
43+
if (session.getJibriType().equals(jibriType)
44+
&& selector.apply(session))
45+
{
46+
count++;
47+
}
48+
}
49+
50+
return count;
51+
}
52+
53+
/**
54+
* Counts pending Jibri sessions of given type.
55+
* @param sessions the list of sessions to scan.
56+
* @param jibriType the type of Jibri session to count.
57+
* @return how many Jibri sessions of given type and in the pending state
58+
* are there on the list.
59+
*/
60+
private static int countPending(List<JibriSession> sessions,
61+
JibriSessionEvent.Type jibriType)
62+
{
63+
return countJibris(sessions, jibriType, JibriSession::isPending);
64+
}
65+
66+
/**
67+
* How many active recording Jibri sessions.
68+
*/
69+
private int activeRecordingSessions;
70+
71+
/**
72+
* How many active lice streaming Jibri sessions.
73+
*/
74+
private int activeLiveStreamingSessions;
75+
76+
/**
77+
* How many active SIP call Jibri sessions.
78+
*/
79+
private int activeSipCallSessions;
80+
81+
/**
82+
* How many pending recording Jibri sessions.
83+
*/
84+
private int pendingRecordingSessions;
85+
86+
/**
87+
* How many pending live streaming Jibri sessions
88+
*/
89+
private int pendingLiveStreamingSessions;
90+
91+
/**
92+
* How many pending SIP call Jibri sessions.
93+
*/
94+
private int pendingSipCallSessions;
95+
96+
/**
97+
* Creates empty instance initialized with 0 stats.
98+
*/
99+
public JibriSessionStats()
100+
{
101+
102+
}
103+
104+
/**
105+
* Creates new {@link JibriSessionStats} computed for the given list of
106+
* {@link JibriSession}.
107+
*
108+
* @param sessions the list for which the stats will be generated.
109+
*/
110+
public JibriSessionStats(List<JibriSession> sessions)
111+
{
112+
activeLiveStreamingSessions
113+
= countActive(
114+
sessions,
115+
JibriSessionEvent.Type.LIVE_STREAMING);
116+
activeRecordingSessions
117+
= countActive(
118+
sessions,
119+
JibriSessionEvent.Type.RECORDING);
120+
activeSipCallSessions
121+
= countActive(
122+
sessions,
123+
JibriSessionEvent.Type.SIP_CALL);
124+
125+
pendingLiveStreamingSessions
126+
= countPending(
127+
sessions,
128+
JibriSessionEvent.Type.LIVE_STREAMING);
129+
pendingRecordingSessions
130+
= countPending(
131+
sessions,
132+
JibriSessionEvent.Type.RECORDING);
133+
pendingSipCallSessions
134+
= countPending(
135+
sessions,
136+
JibriSessionEvent.Type.SIP_CALL);
137+
}
138+
139+
/**
140+
* Merges statistics stored in the given instance with this instance's
141+
* state by adding up values.
142+
* @param stats the other stats to merge.
143+
*/
144+
public void merge(JibriSessionStats stats)
145+
{
146+
this.activeLiveStreamingSessions += stats.activeLiveStreamingSessions;
147+
this.activeRecordingSessions += stats.activeRecordingSessions;
148+
this.activeSipCallSessions += stats.activeSipCallSessions;
149+
this.pendingLiveStreamingSessions += stats.pendingLiveStreamingSessions;
150+
this.pendingRecordingSessions += stats.pendingRecordingSessions;
151+
this.pendingSipCallSessions += stats.pendingSipCallSessions;
152+
}
153+
154+
/**
155+
* Describes as JSON.
156+
* @param stats the JSON object where the stats will end up.
157+
*/
158+
public void toJSON(JSONObject stats)
159+
{
160+
stats.put("live_streaming_active", activeLiveStreamingSessions);
161+
stats.put("recording_active", activeRecordingSessions);
162+
stats.put("sip_call_active", activeSipCallSessions);
163+
164+
stats.put("live_streaming_pending", pendingLiveStreamingSessions);
165+
stats.put("recording_pending", pendingRecordingSessions);
166+
stats.put("sip_call_pending", pendingSipCallSessions);
167+
}
168+
}

src/main/java/org/jitsi/jicofo/recording/jibri/JibriSipGateway.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,19 @@ protected JibriSession getJibriSessionForMeetIq(JibriIq iq)
125125
return sipSessions.get(sipAddress);
126126
}
127127

128+
/**
129+
* {@inheritDoc}
130+
*/
131+
@Override
132+
public List<JibriSession> getJibriSessions()
133+
{
134+
List<JibriSession> sessions = new ArrayList<>(sipSessions.size());
135+
136+
sessions.addAll(sipSessions.values());
137+
138+
return sessions;
139+
}
140+
128141
@Override
129142
protected IQ handleStartRequest(JibriIq iq)
130143
{

0 commit comments

Comments
 (0)