micrometer-metrics/micrometer
View on GitHubBetter support for working with Observation from Kotlin
Open
#4754 opened on Feb 15, 2024
enhancementhelp wantedkotlinmodule: micrometer-observation
Description
Right now (as far as I can tell), there is no extra support for using Observation API from Kotlin code.
For example, to create a new Observation in normal, blocking code, one first needs to invent a convenience function like this:
private fun <T> ObservationRegistry.observeNotNull(name: String, block: () -> T): T =
Observation.start(name, this).observe(Supplier { block() })!!
And when it comes to wrapping a suspending block of code within Observation it gets even more complicated:
private suspend fun <T> ObservationRegistry.observe(name: String, block: suspend () -> T): T {
val observation = Observation.createNotStarted(name, this)
observation.start()
return try {
mono(observationRegistry.asContextElement() + Dispatchers.Unconfined) {
block()
}.contextWrite { context ->
// XXX this seems to be the safest option of making the new observation current
context.put(ObservationThreadLocalAccessor.KEY, observation)
}.awaitSingle()
} catch (error: Throwable) {
throw error
} finally {
// XXX or maybe it's safer to stop this in `doOnTerminate` of the created mono?
observation.stop()
}
}
At the same time, when working with Otel APIs directly, there is an option to construct a span/context and put it into scope via Otel's ContextExtensions.kt