1 /* 2 * Copyright @ 2015 - Present, 8x8 Inc 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.jitsi.videobridge.eventadmin.callstats; 17 18 import org.jitsi.nlj.stats.*; 19 import org.jitsi.nlj.transform.node.incoming.*; 20 import org.jitsi.nlj.transform.node.outgoing.*; 21 import org.jitsi.stats.media.*; 22 import org.jitsi.videobridge.*; 23 24 import java.util.*; 25 26 /** 27 * Extends a {@link AbstractStatsPeriodicRunnable} which periodically generates 28 * a statistics for the conference channels. 29 * 30 * @author Damian Minkov 31 */ 32 public class ConferencePeriodicRunnable 33 extends AbstractStatsPeriodicRunnable<Conference> 34 { 35 /** 36 * Constructs <tt>ConferencePeriodicRunnable</tt>. 37 * @param conference the conference. 38 * @param period the reporting interval. 39 * @param statsService the StatsService to use for reporting. 40 * @param conferenceIDPrefix prefix to use when creating conference IDs. 41 * @param initiatorID the id which identifies the current bridge. 42 */ ConferencePeriodicRunnable( Conference conference, long period, StatsService statsService, String conferenceIDPrefix, String initiatorID)43 ConferencePeriodicRunnable( 44 Conference conference, 45 long period, 46 StatsService statsService, 47 String conferenceIDPrefix, 48 String initiatorID) 49 { 50 super(conference, 51 period, 52 statsService, 53 conference.getName() == null 54 ? "null" : conference.getName().toString(), 55 conferenceIDPrefix, 56 initiatorID); 57 } 58 59 /** 60 * {@inheritDoc} 61 */ 62 @Override getEndpointStats()63 protected List<EndpointStats> getEndpointStats() 64 { 65 List<EndpointStats> allEndpointStats = new LinkedList<>(); 66 67 for (Endpoint endpoint : o.getLocalEndpoints()) 68 { 69 String id = endpoint.getStatsId(); 70 if (id == null) 71 { 72 id = endpoint.getID(); 73 } 74 EndpointStats endpointStats = new EndpointStats(id); 75 76 TransceiverStats transceiverStats 77 = endpoint.getTransceiver().getTransceiverStats(); 78 int rttMs 79 = (int) transceiverStats.getEndpointConnectionStats().getRtt(); 80 81 Map<Long, IncomingSsrcStats.Snapshot> incomingStats 82 = transceiverStats.getIncomingStats().getSsrcStats(); 83 incomingStats.forEach((ssrc, stats) -> 84 { 85 SsrcStats receiveStats = new SsrcStats(); 86 receiveStats.ssrc = ssrc; 87 receiveStats.bytes = stats.getNumReceivedBytes(); 88 receiveStats.packets = stats.getNumReceivedPackets(); 89 receiveStats.packetsLost = stats.getCumulativePacketsLost(); 90 receiveStats.rtt_ms = rttMs; 91 // TODO: the incoming stats don't have the fractional packet 92 // loss, it has to be computed between snapshots. 93 //receiveStats.fractionalPacketLoss = TODO; 94 receiveStats.jitter_ms = stats.getJitter(); 95 endpointStats.addReceiveStats(receiveStats); 96 }); 97 98 Map<Long, OutgoingSsrcStats.Snapshot> outgoingStats 99 = transceiverStats.getOutgoingStats().getSsrcStats(); 100 outgoingStats.forEach((ssrc, stats) -> 101 { 102 SsrcStats sendStats = new SsrcStats(); 103 sendStats.ssrc = ssrc; 104 sendStats.bytes = stats.getOctetCount(); 105 sendStats.packets = stats.getPacketCount(); 106 // TODO: we don't keep track of outgoing loss per ssrc. 107 //sendStats.packetsLost = TODO 108 sendStats.rtt_ms = rttMs; 109 // TODO: we don't keep track of outgoing loss per ssrc. 110 //sendStats.fractionalPacketLoss = TODO 111 // TODO: we don't keep track of outgoing loss per ssrc. 112 //sendStats.jitter_ms = TODO 113 endpointStats.addSendStats(sendStats); 114 }); 115 116 allEndpointStats.add(endpointStats); 117 } 118 119 return allEndpointStats; 120 } 121 } 122