Skip to content

Commit 4d9daea

Browse files
authored
feat: replacing micrometer with metrics (#112)
1 parent 38bfe6e commit 4d9daea

File tree

12 files changed

+79
-218
lines changed

12 files changed

+79
-218
lines changed

build.gradle.kts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,7 @@ dependencies {
4444

4545
implementation("io.github.microutils:kotlin-logging:3.0.5")
4646
implementation("org.slf4j:slf4j-jdk14:2.0.12")
47-
implementation("io.micrometer:micrometer-core:1.17.0-M1")
48-
implementation("io.micrometer:micrometer-registry-influx:1.17.0-M1")
49-
implementation("io.micrometer:micrometer-tracing:1.7.0-M1")
50-
implementation("io.micrometer:micrometer-tracing-bridge-otel:1.7.0-M1")
51-
implementation("io.opentelemetry:opentelemetry-exporter-zipkin:1.58.0")
52-
implementation("io.opentelemetry.semconv:opentelemetry-semconv:1.39.0")
47+
implementation("io.dropwizard.metrics5:metrics-core:5.0.6")
5348

5449
implementation("org.pkl-lang:pkl-config-java:0.30.2")
5550
implementation("org.pkl-lang:pkl-codegen-java:0.30.2")

metrics/.gitkeep

Whitespace-only changes.

src/main/kotlin/at/ac/uibk/dps/cirrina/Cirrina.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ class Cirrina {
1515
logger.info { "cirrina version ${getBuildVersion()}" }
1616
logger.info { component.identifier() }
1717

18-
runCatching {
19-
component.persistentContext().use { _ -> component.runtime().run() }
20-
21-
component.meterRegistry().close()
22-
}
18+
runCatching { component.persistentContext().use { _ -> component.runtime().run() } }
2319
.onFailure { ex -> logger.error(ex) { "a fatal error occurred during runtime execution" } }
2420
}
2521

src/main/kotlin/at/ac/uibk/dps/cirrina/EnvironmentVariables.kt

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,8 @@ object EnvironmentVariables {
2424
val zenohEventHandlerConfigUri =
2525
EnvironmentVariable<String?>("ZENOH_EVENT_HANDLER_CONFIG_URI", null)
2626

27-
val influxMetricUrl = EnvironmentVariable<String?>("INFLUX_METRIC_URL", null)
28-
29-
val influxMetricOrg = EnvironmentVariable("INFLUX_METRIC_ORG", "org")
30-
val influxMetricBucket = EnvironmentVariable("INFLUX_METRIC_BUCKET", "bucket")
31-
val influxMetricToken = EnvironmentVariable("INFLUX_METRIC_TOKEN", "bzO10KmR8x")
32-
val influxMetricStep = EnvironmentVariable("INFLUX_METRIC_STEP", 5000L, { it.toLong() })
33-
34-
val zipkinTraceUrl = EnvironmentVariable<String?>("ZIPKIN_TRACE_URL", null)
27+
val metricsDirectory = EnvironmentVariable("METRICS_DIRECTORY", "metrics")
28+
val metricsPeriod = EnvironmentVariable("METRICS_PERIOD", 1L)
3529

3630
val mainUri = EnvironmentVariable("MAIN_URI", "file:///app/main.pkl")
3731

src/main/kotlin/at/ac/uibk/dps/cirrina/Runtime.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import at.ac.uibk.dps.cirrina.execution.service.ServiceImplementation
1313
import at.ac.uibk.dps.cirrina.execution.service.ServiceImplementationSelector
1414
import at.ac.uibk.dps.cirrina.io.CsmParser
1515
import at.ac.uibk.dps.cirrina.spec.Csml as CsmlSpec
16-
import io.micrometer.core.instrument.MeterRegistry
17-
import io.micrometer.core.instrument.Timer
16+
import io.dropwizard.metrics5.MetricRegistry
17+
import io.dropwizard.metrics5.Timer
1818
import jakarta.inject.Inject
1919
import java.net.URI
2020
import kotlin.time.measureTime
@@ -32,7 +32,7 @@ constructor(
3232
@Main main: URI,
3333
persistentContext: Context?,
3434
stateMachineFactory: StateMachine.Factory,
35-
val meterRegistry: MeterRegistry,
35+
val metricRegistry: MetricRegistry,
3636
) {
3737
val eventHandler = EventHandler()
3838
val extent = persistentContext?.let { Extent.of(it) } ?: Extent.of()
@@ -43,7 +43,7 @@ constructor(
4343

4444
private val graph: EventGraph
4545

46-
private var completion: Timer = meterRegistry.timer("runtime.completionTime")
46+
private var completion: Timer = metricRegistry.timer("runtime.completionTime")
4747

4848
init {
4949
val spec =
@@ -92,7 +92,7 @@ constructor(
9292
fun run() = runBlocking {
9393
measureTime { instances.values.map { it.start() }.joinAll() }
9494
.also {
95-
completion.record(it.toJavaDuration())
95+
completion.update(it.toJavaDuration())
9696
logger.info { "runtime terminated in $it" }
9797
}
9898
}

src/main/kotlin/at/ac/uibk/dps/cirrina/di/CirrinaComponent.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import at.ac.uibk.dps.cirrina.cirrina.di.CirrinaModule
55
import at.ac.uibk.dps.cirrina.cirrina.di.Identifier
66
import at.ac.uibk.dps.cirrina.execution.`object`.Context
77
import dagger.Component
8-
import io.micrometer.core.instrument.MeterRegistry
8+
import io.dropwizard.metrics5.MetricRegistry
99
import jakarta.inject.Singleton
1010

1111
@Singleton
1212
@Component(modules = [CirrinaModule::class])
1313
interface CirrinaComponent {
1414
fun persistentContext(): Context?
1515

16-
fun meterRegistry(): MeterRegistry
16+
fun metricRegistry(): MetricRegistry
1717

1818
fun runtime(): Runtime
1919

src/main/kotlin/at/ac/uibk/dps/cirrina/di/CirrinaModule.kt

Lines changed: 9 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,16 @@ import at.ac.uibk.dps.cirrina.EnvironmentVariables
44
import at.ac.uibk.dps.cirrina.PersistentContextProvider
55
import at.ac.uibk.dps.cirrina.execution.`object`.Context
66
import at.ac.uibk.dps.cirrina.execution.provider.ContextEtcd
7-
import at.ac.uibk.dps.cirrina.util.getBuildVersion
87
import dagger.Module
98
import dagger.Provides
10-
import io.micrometer.core.instrument.Clock
11-
import io.micrometer.core.instrument.MeterRegistry
12-
import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics
13-
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics
14-
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics
15-
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics
16-
import io.micrometer.core.instrument.binder.system.ProcessorMetrics
17-
import io.micrometer.core.instrument.composite.CompositeMeterRegistry
18-
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler
19-
import io.micrometer.influx.InfluxConfig
20-
import io.micrometer.influx.InfluxMeterRegistry
21-
import io.micrometer.observation.ObservationHandler
22-
import io.micrometer.observation.ObservationRegistry
23-
import io.micrometer.tracing.handler.DefaultTracingObservationHandler
24-
import io.micrometer.tracing.otel.bridge.OtelBaggageManager
25-
import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext
26-
import io.micrometer.tracing.otel.bridge.OtelTracer
27-
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
28-
import io.opentelemetry.context.propagation.ContextPropagators
29-
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter
30-
import io.opentelemetry.sdk.OpenTelemetrySdk
31-
import io.opentelemetry.sdk.resources.Resource
32-
import io.opentelemetry.sdk.trace.SdkTracerProvider
33-
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor
34-
import io.opentelemetry.semconv.ServiceAttributes
9+
import io.dropwizard.metrics5.CsvReporter
10+
import io.dropwizard.metrics5.MetricRegistry
3511
import jakarta.inject.Qualifier
3612
import jakarta.inject.Singleton
3713
import java.net.URI
38-
import java.time.Duration
14+
import java.nio.file.Paths
3915
import java.util.UUID
16+
import java.util.concurrent.TimeUnit
4017

4118
@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class Identifier
4219

@@ -60,92 +37,16 @@ class CirrinaModule {
6037

6138
@Provides
6239
@Singleton
63-
fun provideMeterRegistry(): MeterRegistry {
64-
val compositeRegistry = CompositeMeterRegistry()
65-
66-
EnvironmentVariables.influxMetricUrl.get()?.let { url ->
67-
compositeRegistry.add(createInfluxRegistry(url))
68-
}
69-
70-
return compositeRegistry.apply {
71-
ClassLoaderMetrics().bindTo(this)
72-
JvmMemoryMetrics().bindTo(this)
73-
JvmGcMetrics().bindTo(this)
74-
JvmThreadMetrics().bindTo(this)
75-
ProcessorMetrics().bindTo(this)
76-
}
77-
}
78-
79-
@Provides
80-
@Singleton
81-
fun provideObservationRegistry(
82-
@Identifier identifier: String,
83-
meterRegistry: MeterRegistry,
84-
): ObservationRegistry {
85-
val observationRegistry = ObservationRegistry.create()
86-
87-
val traceUrl = EnvironmentVariables.zipkinTraceUrl.get() ?: return observationRegistry
88-
89-
val zipkinExporter = ZipkinSpanExporter.builder().setEndpoint(traceUrl).build()
90-
91-
val sdkTracerProvider =
92-
SdkTracerProvider.builder()
93-
.addSpanProcessor(BatchSpanProcessor.builder(zipkinExporter).build())
94-
.setResource(
95-
Resource.getDefault()
96-
.toBuilder()
97-
.put(ServiceAttributes.SERVICE_NAME, identifier)
98-
.put(ServiceAttributes.SERVICE_VERSION, getBuildVersion())
99-
.build()
100-
)
101-
.build()
102-
103-
val openTelemetry =
104-
OpenTelemetrySdk.builder()
105-
.setTracerProvider(sdkTracerProvider)
106-
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
107-
.build()
108-
109-
val otelTracer = openTelemetry.getTracer("io.micrometer.tracing")
110-
val otelCurrentTraceContext = OtelCurrentTraceContext()
111-
val baggageManager = OtelBaggageManager(otelCurrentTraceContext, emptyList(), emptyList())
112-
113-
val otelTracerBridge = OtelTracer(otelTracer, otelCurrentTraceContext, {}, baggageManager)
114-
115-
return observationRegistry.apply {
116-
observationConfig()
117-
.observationHandler(
118-
ObservationHandler.FirstMatchingCompositeObservationHandler(
119-
DefaultTracingObservationHandler(otelTracerBridge),
120-
DefaultMeterObservationHandler(meterRegistry),
121-
)
122-
)
40+
fun provideMeterRegistry(): MetricRegistry =
41+
MetricRegistry().apply {
42+
CsvReporter.forRegistry(this)
43+
.build(Paths.get(EnvironmentVariables.metricsDirectory.get()).toAbsolutePath().toFile())
44+
.start(EnvironmentVariables.metricsPeriod.get(), TimeUnit.SECONDS)
12345
}
124-
}
12546

12647
@Provides @Singleton @Identifier fun provideIdentifier(): String = "cirrina.${UUID.randomUUID()}"
12748

12849
@Provides @Singleton @Main fun provideMain(): URI = URI(EnvironmentVariables.mainUri.get())
12950

13051
@Provides @Singleton @Run fun provideRun(): List<String> = EnvironmentVariables.run.get()
131-
132-
private fun createInfluxRegistry(url: String): InfluxMeterRegistry {
133-
val config =
134-
object : InfluxConfig {
135-
override fun step(): Duration =
136-
Duration.ofMillis(EnvironmentVariables.influxMetricStep.get())
137-
138-
override fun uri(): String = url
139-
140-
override fun org(): String = EnvironmentVariables.influxMetricOrg.get()
141-
142-
override fun bucket(): String = EnvironmentVariables.influxMetricBucket.get()
143-
144-
override fun token(): String = EnvironmentVariables.influxMetricToken.get()
145-
146-
override fun get(k: String): String? = null
147-
}
148-
149-
return InfluxMeterRegistry(config, Clock.SYSTEM)
150-
}
15152
}

src/main/kotlin/at/ac/uibk/dps/cirrina/execution/object/Action.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ sealed interface Action {
4141

4242
is LogDescription -> LogAction(Expression.create(description.message))
4343

44-
is IncrCtrDescription ->
45-
IncrCtrAction(
44+
is CtrDescription ->
45+
CtrAction(
4646
description.counter,
47-
description.by ?: "1.0",
47+
description.by,
4848
description.tags?.mapValues { (_, v) -> Expression.create(v) } ?: emptyMap(),
4949
)
5050

@@ -115,8 +115,7 @@ class TimeoutResetAction internal constructor(val action: String) : Action {
115115

116116
class LogAction internal constructor(val message: Expression) : Action
117117

118-
class IncrCtrAction
119-
internal constructor(val counter: String, val by: String, val tag: Map<String, Expression>) :
120-
Action {
121-
override fun toString() = "IncrCtrAction(metric='$counter', by='$by', tag='$tag')"
118+
class CtrAction
119+
internal constructor(val counter: String, val by: Long, val tag: Map<String, Expression>) : Action {
120+
override fun toString() = "CtrAction(metric='$counter', by='$by', tag='$tag')"
122121
}

src/main/kotlin/at/ac/uibk/dps/cirrina/execution/object/ActionCommand.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ package at.ac.uibk.dps.cirrina.execution.`object`
22

33
import at.ac.uibk.dps.cirrina.csm.Csml.EventChannel
44
import at.ac.uibk.dps.cirrina.execution.service.ServiceImplementationSelector
5-
import io.micrometer.core.instrument.MeterRegistry
6-
import io.micrometer.core.instrument.Tag
7-
import io.micrometer.core.instrument.Tags
5+
import io.dropwizard.metrics5.MetricName
6+
import io.dropwizard.metrics5.MetricRegistry
87
import kotlinx.coroutines.CoroutineScope
98
import kotlinx.coroutines.launch
109
import mu.KotlinLogging
@@ -17,9 +16,9 @@ interface Scope {
1716

1817
class ActionExecutor(
1918
private val selector: ServiceImplementationSelector,
19+
private val metricRegistry: MetricRegistry,
2020
private val eventHandler: StateMachine.StateMachineEventHandler,
2121
private val coroutineScope: CoroutineScope,
22-
private val meterRegistry: MeterRegistry,
2322
) {
2423
fun execute(action: Action, scope: Scope): List<Action> =
2524
when (action) {
@@ -30,7 +29,7 @@ class ActionExecutor(
3029
is TimeoutAction -> listOf(action.triggers)
3130
is TimeoutResetAction -> emptyList()
3231
is LogAction -> executeLog(action, scope)
33-
is IncrCtrAction -> executeIncrCtr(action, scope)
32+
is CtrAction -> executeCtr(action, scope)
3433
else -> error("unknown action type: ${action::class.simpleName}")
3534
}
3635

@@ -90,12 +89,13 @@ class ActionExecutor(
9089
return emptyList()
9190
}
9291

93-
private fun executeIncrCtr(action: IncrCtrAction, scope: Scope): List<Action> {
92+
private fun executeCtr(action: CtrAction, scope: Scope): List<Action> {
9493
val tags =
95-
Tags.of(
96-
action.tag.map { (key, value) -> Tag.of(key, value.execute(scope.extent).toString()) }
97-
)
98-
meterRegistry.counter(action.counter, tags).increment(action.by.toDouble())
94+
action.tag.entries.associate { (key, value) -> key to value.execute(scope.extent).toString() }
95+
96+
val name = MetricName.build(action.counter).tagged(tags)
97+
metricRegistry.counter(name).inc(action.by)
98+
9999
return emptyList()
100100
}
101101
}

0 commit comments

Comments
 (0)