August Lilleaas
08/04/2025, 4:48 PMsuspend fun <T> CoroutineScope.logSlowQueries(
timeoutSeconds: Long?,
block: suspend () -> T
): T {
val slowQueryDetectorJob = async {
delay(Duration.ofSeconds(timeoutSeconds ?: 10))
val otelCtx = Span.current().spanContext
if (otelCtx.isValid) {
log.error("Query not completed after $timeoutSeconds seconds - traceId=${otelCtx.traceId} spanId=${otelCtx.spanId}")
} else {
log.error("Query not completed after $timeoutSeconds seconds - NO OTEL CTX AVAILABLE")
}
}
return try {
block()
} finally {
slowQueryDetectorJob.cancel()
}
}Szymon Jeziorski
08/05/2025, 2:58 PMmeasureTimedValue be much simpler for the purpose or am I missing something?
inline fun <T> logSlowQueries(
timeoutSeconds: Long = 10,
block: suspend () -> T
): T {
val (result, duration) = measureTimedValue { block() }
if (duration > timeoutSeconds.seconds) {
[logging]
}
return result
}
Also, above function would work both for coroutines and normal sync code due to being inlineAugust Lilleaas
08/06/2025, 6:54 AMmeasureTimedValue 👍August Lilleaas
08/06/2025, 6:56 AMSzymon Jeziorski
08/06/2025, 4:06 PMlouiscad
08/20/2025, 12:41 PMCoroutineScope.
wrap the function content with a local coroutineScope { … } instead.