diff --git a/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java b/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java index 182afbee87..c31ae646aa 100644 --- a/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java +++ b/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java @@ -47,6 +47,7 @@ import org.jivesoftware.smackx.caps.packet.*; import org.jxmpp.jid.*; +import java.time.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -253,6 +254,8 @@ public class JitsiMeetConferenceImpl */ private boolean visitorsBroadcastEnabled = VisitorsConfig.config.getAutoEnableBroadcast(); + @NotNull private final Instant createdInstant = Instant.now(); + /** * The unique meeting ID for this conference. We expect this to be set by the XMPP server in the MUC config form. * If for some reason it's not present, we'll generate a local UUID. The field is nullable, but always non-null @@ -478,6 +481,11 @@ public void stop() } logger.info("Stopped."); + if (includeInStatistics()) + { + ConferenceMetrics.conferenceSeconds.addAndGet( + Duration.between(createdInstant, Instant.now()).toMillis() / 1000.0); + } if (listener != null) { listener.conferenceEnded(this); @@ -1058,6 +1066,10 @@ private void terminateParticipant( "Removed participant " + participant.getChatMember().getName() + " removed=" + (removed != null)); if (!willReinvite && removed != null) { + if (includeInStatistics()) + { + ConferenceMetrics.endpointSeconds.addAndGet(participant.durationSeconds()); + } if (removed.isUserParticipant()) { userParticipantRemoved(); diff --git a/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/ConferenceMetrics.kt b/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/ConferenceMetrics.kt index abee9e4d82..052edd15ba 100644 --- a/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/ConferenceMetrics.kt +++ b/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/ConferenceMetrics.kt @@ -30,6 +30,18 @@ class ConferenceMetrics { "The number of conferences created on this Jicofo since it was started" ) + @JvmField + val conferenceSeconds = metricsContainer.registerDoubleGauge( + "conferences_seconds", + "The duration of completed conferences in seconds." + ) + + @JvmField + val endpointSeconds = metricsContainer.registerDoubleGauge( + "endpoint_seconds", + "The duration of endpoints in a conferences in seconds." + ) + @JvmField val participants = metricsContainer.registerCounter( "participants", diff --git a/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/Participant.kt b/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/Participant.kt index 95e4d477d3..b5e101b7a6 100644 --- a/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/Participant.kt +++ b/jicofo/src/main/kotlin/org/jitsi/jicofo/conference/Participant.kt @@ -71,8 +71,12 @@ open class Participant @JvmOverloads constructor( /** The list of XMPP features supported by this participant. */ val supportedFeatures: Set = Features.defaultFeatures, /** The [Clock] used by this participant. */ - clock: Clock = Clock.systemUTC() + private val clock: Clock = Clock.systemUTC() ) { + private val createdInstant: Instant = clock.instant() + + fun durationSeconds(): Double = Duration.between(createdInstant, clock.instant()).toMillis() / 1000.0 + /** The endpoint ID for this participant in the videobridge (Colibri) context. */ val endpointId: String = chatMember.name