From c7557cedcd59e1842bb3fbfe4ecdde047dad7fb0 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Mon, 16 Dec 2024 19:07:59 -0600 Subject: [PATCH 1/2] fix: Log exceptions from the queue (e.g. from jebml). --- src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt b/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt index 882c9ff..2649a91 100644 --- a/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt +++ b/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt @@ -24,6 +24,7 @@ import org.jitsi.recorder.opus.GapTooLargeException import org.jitsi.recorder.opus.OpusPacket import org.jitsi.recorder.opus.PacketLossConcealmentInserter import org.jitsi.utils.logging2.Logger +import org.jitsi.utils.queue.ErrorHandler import org.jitsi.utils.queue.PacketQueue import java.io.File import java.time.Clock @@ -43,6 +44,11 @@ class MediaJsonMkaRecorder(directory: File, parentLogger: Logger) : MediaJsonRec val queue = EventQueue { handleEvent(it) true + }.also { + it.setErrorHandler(object : ErrorHandler { + override fun packetDropped() = logger.warn("Dropped an event.") + override fun packetHandlingFailed(t: Throwable) = logger.error("Error handling event: ", t) + }) } private val trackRecorders = mutableMapOf() From e20a963b764df9b5a797782f32feef506dae7ca7 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Mon, 16 Dec 2024 19:14:31 -0600 Subject: [PATCH 2/2] Add metrics and assert no exceptions or dropped events during tests. --- .../kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt | 10 ++++++++-- src/main/kotlin/org/jitsi/recorder/RecorderMetrics.kt | 2 ++ .../kotlin/org/jitsi/recorder/KotestProjectConfig.kt | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt b/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt index 2649a91..4cb01df 100644 --- a/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt +++ b/src/main/kotlin/org/jitsi/recorder/MediaJsonMkaRecorder.kt @@ -46,8 +46,14 @@ class MediaJsonMkaRecorder(directory: File, parentLogger: Logger) : MediaJsonRec true }.also { it.setErrorHandler(object : ErrorHandler { - override fun packetDropped() = logger.warn("Dropped an event.") - override fun packetHandlingFailed(t: Throwable) = logger.error("Error handling event: ", t) + override fun packetDropped() { + logger.warn("Dropped an event.") + RecorderMetrics.instance.queueEventsDropped.inc() + } + override fun packetHandlingFailed(t: Throwable) { + logger.error("Error handling event: ", t) + RecorderMetrics.instance.queueExceptions.inc() + } }) } private val trackRecorders = mutableMapOf() diff --git a/src/main/kotlin/org/jitsi/recorder/RecorderMetrics.kt b/src/main/kotlin/org/jitsi/recorder/RecorderMetrics.kt index fad9bc6..1074358 100644 --- a/src/main/kotlin/org/jitsi/recorder/RecorderMetrics.kt +++ b/src/main/kotlin/org/jitsi/recorder/RecorderMetrics.kt @@ -32,6 +32,8 @@ class RecorderMetrics private constructor() : MetricsContainer(namespace = "jits "plc_milliseconds", "Duration of recorded packet concealment packets in milliseconds" ) + val queueEventsDropped = registerCounter("queue_events_dropped", "Number of events dropped") + val queueExceptions = registerCounter("queue_exceptions", "Number of exceptions from the event queue") companion object { /** diff --git a/src/test/kotlin/org/jitsi/recorder/KotestProjectConfig.kt b/src/test/kotlin/org/jitsi/recorder/KotestProjectConfig.kt index 4869d59..927b4b9 100644 --- a/src/test/kotlin/org/jitsi/recorder/KotestProjectConfig.kt +++ b/src/test/kotlin/org/jitsi/recorder/KotestProjectConfig.kt @@ -18,6 +18,7 @@ package org.jitsi.recorder import io.kotest.core.config.AbstractProjectConfig +import io.kotest.matchers.shouldBe import org.jitsi.metaconfig.MetaconfigSettings class KotestProjectConfig : AbstractProjectConfig() { @@ -26,4 +27,8 @@ class KotestProjectConfig : AbstractProjectConfig() { // freely modify the config without affecting other tests executing afterwards). MetaconfigSettings.cacheEnabled = false } + override suspend fun afterProject() = super.afterProject().also { + RecorderMetrics.instance.queueExceptions.get() shouldBe 0 + RecorderMetrics.instance.queueEventsDropped.get() shouldBe 0 + } }