This commit is contained in:
Menci
2024-12-10 23:30:30 +08:00
parent db5343fba3
commit 340003c568
14 changed files with 208 additions and 31 deletions

View File

@@ -5,6 +5,9 @@ import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*
import io.micrometer.core.instrument.*
import io.micrometer.core.instrument.Timer
import io.micrometer.core.instrument.Metrics as Micrometer
import jakarta.persistence.Query
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -22,6 +25,7 @@ import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.reflect.KCallable
import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
@@ -214,3 +218,45 @@ val <S> Pair<*, S>.r get() = component2()
// Database
val Query.exec get() = resultList.map { (it as Array<*>).toList() }
// Metrics
object Metrics {
@PublishedApi
internal inline fun <reified T : Any> expandLabels(labels: T): Array<String> {
return T::class.memberProperties.flatMap { prop ->
listOf(prop.name, prop.get(labels)?.toString() ?: throw IllegalArgumentException("Missing value for label ${prop.name}"))
}.toTypedArray()
}
@PublishedApi
internal data class MetricCacheKey(val metricName: String, val labels: Any)
@PublishedApi
internal val counterCache = ConcurrentHashMap<MetricCacheKey, Counter>()
inline fun <reified T : Any> counter(metricName: String): (T) -> Counter {
return { labels ->
counterCache.computeIfAbsent(MetricCacheKey(metricName, labels)) {
Counter
.builder(metricName)
.tags(*expandLabels(labels))
.register(Micrometer.globalRegistry)
}
}
}
@PublishedApi
internal val timerCache = ConcurrentHashMap<MetricCacheKey, Timer>()
inline fun <reified T : Any> timer(metricName: String): (T) -> Timer {
return { labels ->
timerCache.computeIfAbsent(MetricCacheKey(metricName, labels)) {
Timer
.builder(metricName)
.publishPercentiles(0.5, 0.75, 0.90, 0.95, 0.99)
.tags(*expandLabels(labels))
.register(Micrometer.globalRegistry)
}
}
}
}