From 9d20768a5fa96976b308b147b4434e901097c15a Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Wed, 4 Jun 2025 14:56:13 -0400 Subject: [PATCH] Make MetricsCategory an interface and add default tags (#1088) * Make MetricsCategory an interface and add default tags * Make metric category non nullable * Fix jacoco report failure * fix spotless --- .../linea/metrics/LineaMetricsCategory.kt | 9 +++ .../linea/jsonrpc/JsonRpcMessageProcessor.kt | 22 ++++-- .../jsonrpc/client/VertxHttpJsonRpcClient.kt | 7 +- .../consensys/linea/metrics/MetricsFacade.kt | 24 ++----- .../micrometer/DynamicTagTimerCapture.kt | 9 +-- .../linea/metrics/micrometer/Extensions.kt | 7 ++ .../micrometer/MicrometerMetricsFacade.kt | 71 ++++++++----------- .../micrometer/MicrometerMetricsFacadeTest.kt | 71 +++++++++++++------ .../metrics/LineaMetricsCategory.kt | 7 ++ .../TransactionExclusionServiceV1Impl.kt | 2 +- 10 files changed, 134 insertions(+), 95 deletions(-) create mode 100644 coordinator/core/src/main/kotlin/net/consensys/linea/metrics/LineaMetricsCategory.kt create mode 100644 jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/Extensions.kt create mode 100644 transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/metrics/LineaMetricsCategory.kt diff --git a/coordinator/core/src/main/kotlin/net/consensys/linea/metrics/LineaMetricsCategory.kt b/coordinator/core/src/main/kotlin/net/consensys/linea/metrics/LineaMetricsCategory.kt new file mode 100644 index 00000000..9bd5b9cb --- /dev/null +++ b/coordinator/core/src/main/kotlin/net/consensys/linea/metrics/LineaMetricsCategory.kt @@ -0,0 +1,9 @@ +package net.consensys.linea.metrics + +enum class LineaMetricsCategory : MetricsCategory { + AGGREGATION, + BATCH, + BLOB, + CONFLATION, + GAS_PRICE_CAP, +} diff --git a/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/JsonRpcMessageProcessor.kt b/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/JsonRpcMessageProcessor.kt index 247e33b3..847919c5 100644 --- a/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/JsonRpcMessageProcessor.kt +++ b/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/JsonRpcMessageProcessor.kt @@ -22,6 +22,7 @@ import io.vertx.core.json.JsonObject import io.vertx.core.json.jackson.DatabindCodec import io.vertx.core.json.jackson.VertxModule import io.vertx.ext.auth.User +import net.consensys.linea.metrics.MetricsCategory import net.consensys.linea.metrics.MetricsFacade import net.consensys.linea.metrics.Tag import org.apache.logging.log4j.LogManager @@ -56,6 +57,9 @@ class JsonRpcMessageProcessor( private val log: Logger = LogManager.getLogger(JsonRpcMessageProcessor::class.java), private val responseResultObjectMapper: ObjectMapper = jacksonObjectMapper().registerModules(VertxModule()), private val rpcEnvelopeObjectMapper: ObjectMapper = jacksonObjectMapper(), + private val metricsCategory: MetricsCategory = object : MetricsCategory { + override val name: String = "jsonrpc" + }, ) : JsonRpcMessageHandler { init { DatabindCodec.mapper().registerKotlinModule() @@ -70,7 +74,8 @@ class JsonRpcMessageProcessor( ): Future { return Future.fromCompletionStage( metricsFacade.createDynamicTagTimer>( - name = "jsonrpc.processing.whole", + category = metricsCategory, + name = "processing.whole", description = "Processing of JSON-RPC message: Deserialization + Business Logic + Serialization", tagKey = "method", tagValueExtractorOnError = { "METHOD_PROCESSING_ERROR" }, @@ -175,7 +180,8 @@ class JsonRpcMessageProcessor( responses.first() } else { metricsFacade.createSimpleTimer( - name = "jsonrpc.serialization.response.bulk", + category = metricsCategory, + name = "serialization.response.bulk", description = "Time of bulk json response serialization", ).captureTime { responses.joinToString(",", "[", "]") } } @@ -187,7 +193,8 @@ class JsonRpcMessageProcessor( json: Any, ): Result, JsonRpcErrorResponse> { return metricsFacade.createDynamicTagTimer( - name = "jsonrpc.serialization.request", + category = metricsCategory, + name = "serialization.request", description = "json-rpc method parsing", tagKey = "method", tagValueExtractorOnError = { "METHOD_PARSE_ERROR" }, @@ -199,7 +206,8 @@ class JsonRpcMessageProcessor( private fun encodeAndMeasureResponse(requestContext: RequestContext): String { val timerCapture = metricsFacade.createSimpleTimer( - name = "jsonrpc.serialization.response", + category = metricsCategory, + name = "serialization.response", description = "Time of json response serialization", tags = listOf(Tag("method", requestContext.method)), ) @@ -219,7 +227,8 @@ class JsonRpcMessageProcessor( requestJson: JsonObject, ): Future> { return metricsFacade.createSimpleTimer>>( - name = "jsonrpc.processing.logic", + category = metricsCategory, + name = "processing.logic", description = "Processing of a particular JRPC method's logic without SerDes", tags = listOf(Tag("method", jsonRpcRequest.method)), ) @@ -227,7 +236,8 @@ class JsonRpcMessageProcessor( .onComplete { result: AsyncResult> -> val success = (result.succeeded() && result.result() is Ok) metricsFacade.createCounter( - name = "jsonrpc.counter", + category = metricsCategory, + name = "counter", description = "Counting the JSON rpc request with result and method", tags = listOf( Tag("success", success.toString()), diff --git a/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClient.kt b/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClient.kt index 61f72362..dc0181a2 100644 --- a/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClient.kt +++ b/jvm-libs/generic/json-rpc/src/main/kotlin/net/consensys/linea/jsonrpc/client/VertxHttpJsonRpcClient.kt @@ -18,6 +18,7 @@ import net.consensys.linea.jsonrpc.JsonRpcErrorResponse import net.consensys.linea.jsonrpc.JsonRpcRequest import net.consensys.linea.jsonrpc.JsonRpcRequestData import net.consensys.linea.jsonrpc.JsonRpcSuccessResponse +import net.consensys.linea.metrics.MetricsCategory import net.consensys.linea.metrics.MetricsFacade import net.consensys.linea.metrics.Tag import org.apache.logging.log4j.Level @@ -35,6 +36,9 @@ class VertxHttpJsonRpcClient( private val log: Logger = LogManager.getLogger(VertxHttpJsonRpcClient::class.java), private val requestResponseLogLevel: Level = Level.TRACE, private val failuresLogLevel: Level = Level.DEBUG, + private val metricsCategory: MetricsCategory = object : MetricsCategory { + override val name: String = "jsonrpc" + }, ) : JsonRpcClient { private val requestOptions = RequestOptions().apply { setMethod(HttpMethod.POST) @@ -87,7 +91,8 @@ class VertxHttpJsonRpcClient( Future.fromCompletionStage( metricsFacade.createSimpleTimer>( - name = "jsonrpc.request", + category = metricsCategory, + name = "request", description = "Time of Upstream API JsonRpc Requests", tags = listOf( Tag("endpoint", endpoint.host), diff --git a/jvm-libs/linea/core/metrics/src/main/kotlin/net/consensys/linea/metrics/MetricsFacade.kt b/jvm-libs/linea/core/metrics/src/main/kotlin/net/consensys/linea/metrics/MetricsFacade.kt index 23f823ca..c1afcddc 100644 --- a/jvm-libs/linea/core/metrics/src/main/kotlin/net/consensys/linea/metrics/MetricsFacade.kt +++ b/jvm-libs/linea/core/metrics/src/main/kotlin/net/consensys/linea/metrics/MetricsFacade.kt @@ -7,18 +7,8 @@ import java.util.function.Supplier data class Tag(val key: String, val value: String) -enum class LineaMetricsCategory { - AGGREGATION, - BATCH, - BLOB, - CONFLATION, - GAS_PRICE_CAP, - TX_EXCLUSION_API, - ; - - override fun toString(): String { - return this.name.replace('_', '.').lowercase() - } +interface MetricsCategory { + val name: String } interface Counter { @@ -38,7 +28,7 @@ interface TimerCapture { interface MetricsFacade { fun createGauge( - category: LineaMetricsCategory? = null, + category: MetricsCategory, name: String, description: String, measurementSupplier: Supplier, @@ -46,14 +36,14 @@ interface MetricsFacade { ) fun createCounter( - category: LineaMetricsCategory? = null, + category: MetricsCategory, name: String, description: String, tags: List = emptyList(), ): Counter fun createHistogram( - category: LineaMetricsCategory? = null, + category: MetricsCategory, name: String, description: String, tags: List = emptyList(), @@ -62,14 +52,14 @@ interface MetricsFacade { ): Histogram fun createSimpleTimer( - category: LineaMetricsCategory? = null, + category: MetricsCategory, name: String, description: String, tags: List = emptyList(), ): TimerCapture fun createDynamicTagTimer( - category: LineaMetricsCategory? = null, + category: MetricsCategory, name: String, description: String, tagKey: String, diff --git a/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/DynamicTagTimerCapture.kt b/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/DynamicTagTimerCapture.kt index 5dd3a124..3e85bc65 100644 --- a/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/DynamicTagTimerCapture.kt +++ b/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/DynamicTagTimerCapture.kt @@ -21,10 +21,6 @@ class DynamicTagTimerCapture : AbstractTimerCapture, TimerCapture { private var tagKey: String? = null constructor(meterRegistry: MeterRegistry, name: String) : super(meterRegistry, name) - constructor( - meterRegistry: MeterRegistry, - timerBuilder: Timer.Builder, - ) : super(meterRegistry, timerBuilder) override fun setDescription(description: String): DynamicTagTimerCapture { super.setDescription(description) @@ -32,9 +28,8 @@ class DynamicTagTimerCapture : AbstractTimerCapture, TimerCapture { } override fun setTag(tagKey: String, tagValue: String): DynamicTagTimerCapture { - throw NoSuchMethodException( - "If you need to set both value and key, please use ${SimpleTimerCapture::class.qualifiedName}", - ) + super.setTag(tagKey, tagValue) + return this } override fun setClock(clock: Clock): DynamicTagTimerCapture { diff --git a/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/Extensions.kt b/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/Extensions.kt new file mode 100644 index 00000000..d6d723aa --- /dev/null +++ b/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/Extensions.kt @@ -0,0 +1,7 @@ +package net.consensys.linea.metrics.micrometer + +import net.consensys.linea.metrics.MetricsCategory + +fun MetricsCategory.toValidMicrometerName(): String { + return this.name.lowercase().replace('_', '.') +} diff --git a/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacade.kt b/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacade.kt index 142f3be0..17a0fa41 100644 --- a/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacade.kt +++ b/jvm-libs/linea/metrics/micrometer/src/main/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacade.kt @@ -5,7 +5,7 @@ import io.micrometer.core.instrument.Gauge import io.micrometer.core.instrument.MeterRegistry import net.consensys.linea.metrics.Counter import net.consensys.linea.metrics.Histogram -import net.consensys.linea.metrics.LineaMetricsCategory +import net.consensys.linea.metrics.MetricsCategory import net.consensys.linea.metrics.MetricsFacade import net.consensys.linea.metrics.Tag import net.consensys.linea.metrics.TimerCapture @@ -17,6 +17,7 @@ import io.micrometer.core.instrument.Timer as MicrometerTimer class MicrometerMetricsFacade( private val registry: MeterRegistry, private val metricsPrefix: String? = null, + private val commonTags: List = emptyList(), ) : MetricsFacade { companion object { private val validBaseUnits = listOf( @@ -37,74 +38,64 @@ class MicrometerMetricsFacade( init { if (metricsPrefix != null) requireValidMicrometerName(metricsPrefix) + commonTags.forEach { requireValidMicrometerName(it.key) } } - private fun metricHandle(category: LineaMetricsCategory?, metricName: String): String { + private fun metricHandle(category: MetricsCategory, metricName: String): String { val prefixName = if (metricsPrefix == null) "" else "$metricsPrefix." - val categoryName = if (category == null) "" else "$category." + val categoryName = "${category.toValidMicrometerName()}." return "$prefixName$categoryName$metricName" } + private fun flattenTags(tags: List): List { + tags.forEach { requireValidMicrometerName(it.key) } + return (tags + commonTags).flatMap { + listOf(it.key, it.value) + } + } + override fun createGauge( - category: LineaMetricsCategory?, + category: MetricsCategory, name: String, description: String, measurementSupplier: Supplier, tags: List, ) { - if (category != null) requireValidMicrometerName(category.toString()) + requireValidMicrometerName(category.toValidMicrometerName()) requireValidMicrometerName(name) val builder = Gauge.builder(metricHandle(category, name), measurementSupplier) - if (tags.isNotEmpty()) { - val flatTags = tags.flatMap { - requireValidMicrometerName(it.key) - listOf(it.key, it.value) - } - builder.tags(*flatTags.toTypedArray()) - } + flattenTags(tags).takeIf { it.isNotEmpty() }?.let { builder.tags(*it.toTypedArray()) } builder.description(description) builder.register(registry) } override fun createCounter( - category: LineaMetricsCategory?, + category: MetricsCategory, name: String, description: String, tags: List, ): Counter { - if (category != null) requireValidMicrometerName(category.toString()) + requireValidMicrometerName(category.toValidMicrometerName()) requireValidMicrometerName(name) val builder = MicrometerCounter.builder(metricHandle(category, name)) - if (tags.isNotEmpty()) { - val flatTags = tags.flatMap { - requireValidMicrometerName(it.key) - listOf(it.key, it.value) - } - builder.tags(*flatTags.toTypedArray()) - } + flattenTags(tags).takeIf { it.isNotEmpty() }?.let { builder.tags(*it.toTypedArray()) } builder.description(description) return MicrometerCounterAdapter(builder.register(registry)) } override fun createHistogram( - category: LineaMetricsCategory?, + category: MetricsCategory, name: String, description: String, tags: List, isRatio: Boolean, baseUnit: String?, ): Histogram { - if (category != null) requireValidMicrometerName(category.toString()) + requireValidMicrometerName(category.toValidMicrometerName()) requireValidMicrometerName(name) if (baseUnit != null) requireValidBaseUnit(baseUnit) val distributionSummaryBuilder = DistributionSummary.builder(metricHandle(category, name)) - if (tags.isNotEmpty()) { - val flatTags = tags.flatMap { - requireValidMicrometerName(it.key) - listOf(it.key, it.value) - } - distributionSummaryBuilder.tags(*flatTags.toTypedArray()) - } + flattenTags(tags).takeIf { it.isNotEmpty() }?.let { distributionSummaryBuilder.tags(*it.toTypedArray()) } distributionSummaryBuilder.description(description) distributionSummaryBuilder.baseUnit(baseUnit) if (isRatio) { @@ -115,41 +106,37 @@ class MicrometerMetricsFacade( } override fun createSimpleTimer( - category: LineaMetricsCategory?, + category: MetricsCategory, name: String, description: String, tags: List, ): TimerCapture { - if (category != null) requireValidMicrometerName(category.toString()) + requireValidMicrometerName(category.toValidMicrometerName()) requireValidMicrometerName(name) val builder = MicrometerTimer.builder(metricHandle(category, name)) - if (tags.isNotEmpty()) { - val flatTags = tags.flatMap { - requireValidMicrometerName(it.key) - listOf(it.key, it.value) - } - builder.tags(*flatTags.toTypedArray()) - } + flattenTags(tags).takeIf { it.isNotEmpty() }?.let { builder.tags(*it.toTypedArray()) } builder.description(description) return SimpleTimerCapture(registry, builder) } override fun createDynamicTagTimer( - category: LineaMetricsCategory?, + category: MetricsCategory, name: String, description: String, tagKey: String, tagValueExtractorOnError: Function, tagValueExtractor: Function, ): TimerCapture { - if (category != null) requireValidMicrometerName(category.toString()) + requireValidMicrometerName(category.toValidMicrometerName()) requireValidMicrometerName(name) requireValidMicrometerName(tagKey) - return DynamicTagTimerCapture(registry, metricHandle(category, name)) + val dynamicTagTimerCapture = DynamicTagTimerCapture(registry, metricHandle(category, name)) .setDescription(description) .setTagKey(tagKey) .setTagValueExtractor(tagValueExtractor) .setTagValueExtractorOnError(tagValueExtractorOnError) + commonTags.forEach { dynamicTagTimerCapture.setTag(it.key, it.value) } + return dynamicTagTimerCapture } } diff --git a/jvm-libs/linea/metrics/micrometer/src/test/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacadeTest.kt b/jvm-libs/linea/metrics/micrometer/src/test/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacadeTest.kt index 207dc8ae..03124505 100644 --- a/jvm-libs/linea/metrics/micrometer/src/test/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacadeTest.kt +++ b/jvm-libs/linea/metrics/micrometer/src/test/kotlin/net/consensys/linea/metrics/micrometer/MicrometerMetricsFacadeTest.kt @@ -3,7 +3,7 @@ package net.consensys.linea.metrics.micrometer import io.micrometer.core.instrument.ImmutableTag import io.micrometer.core.instrument.MeterRegistry import io.micrometer.core.instrument.simple.SimpleMeterRegistry -import net.consensys.linea.metrics.LineaMetricsCategory +import net.consensys.linea.metrics.MetricsCategory import net.consensys.linea.metrics.MetricsFacade import net.consensys.linea.metrics.Tag import org.assertj.core.api.Assertions.assertThat @@ -16,10 +16,18 @@ class MicrometerMetricsFacadeTest { private lateinit var meterRegistry: MeterRegistry private lateinit var metricsFacade: MetricsFacade + enum class TestCategory : MetricsCategory { + TEST_CATEGORY, + } + @BeforeEach fun beforeEach() { meterRegistry = SimpleMeterRegistry() - metricsFacade = MicrometerMetricsFacade(meterRegistry, "linea.test") + metricsFacade = MicrometerMetricsFacade( + meterRegistry, + metricsPrefix = "linea.test", + commonTags = listOf(Tag("version", "1.0.1")), + ) } @Test @@ -27,19 +35,23 @@ class MicrometerMetricsFacadeTest { var metricMeasureValue = 0L val expectedTags = listOf(Tag("key1", "value1"), Tag("key2", "value2")) metricsFacade.createGauge( - category = LineaMetricsCategory.BATCH, + category = TestCategory.TEST_CATEGORY, name = "some.metric", description = "This is a test metric", measurementSupplier = { metricMeasureValue }, tags = expectedTags, ) metricMeasureValue = 13L - val createdGauge = meterRegistry.find("linea.test.batch.some.metric").gauge() + val createdGauge = meterRegistry.find("linea.test.test.category.some.metric").gauge() assertThat(createdGauge).isNotNull assertThat(createdGauge!!.value()).isEqualTo(13.0) metricMeasureValue = 2L assertThat(createdGauge.value()).isEqualTo(2.0) - assertThat(createdGauge.id.tags).isEqualTo(listOf(ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2"))) + assertThat( + createdGauge.id.tags, + ).containsAll( + listOf(ImmutableTag("version", "1.0.1"), ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2")), + ) assertThat(createdGauge.id.description).isEqualTo("This is a test metric") } @@ -47,12 +59,12 @@ class MicrometerMetricsFacadeTest { fun `createCounter creates counter with specified parameters`() { val expectedTags = listOf(Tag("key1", "value1"), Tag("key2", "value2")) val counter = metricsFacade.createCounter( - category = LineaMetricsCategory.BATCH, + category = TestCategory.TEST_CATEGORY, name = "some.metric", description = "This is a test metric", tags = expectedTags, ) - val createdCounter = meterRegistry.find("linea.test.batch.some.metric").counter() + val createdCounter = meterRegistry.find("linea.test.test.category.some.metric").counter() assertThat(createdCounter!!.count()).isEqualTo(0.0) assertThat(createdCounter).isNotNull counter.increment(13.0) @@ -64,7 +76,11 @@ class MicrometerMetricsFacadeTest { assertThat(createdCounter.count()).isEqualTo(16.0) counter.increment(0.5) assertThat(createdCounter.count()).isEqualTo(16.5) - assertThat(createdCounter.id.tags).isEqualTo(listOf(ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2"))) + assertThat( + createdCounter.id.tags, + ).containsAll( + listOf(ImmutableTag("version", "1.0.1"), ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2")), + ) assertThat(createdCounter.id.description).isEqualTo("This is a test metric") } @@ -72,18 +88,20 @@ class MicrometerMetricsFacadeTest { fun `createHistogram creates histogram with specified parameters`() { val expectedTags = listOf(Tag("key1", "value1"), Tag("key2", "value2")) val histogram = metricsFacade.createHistogram( - category = LineaMetricsCategory.BATCH, + category = TestCategory.TEST_CATEGORY, name = "some.metric", description = "This is a test metric", tags = expectedTags, baseUnit = "seconds", ) - val createdHistogram = meterRegistry.find("linea.test.batch.some.metric").summary() + val createdHistogram = meterRegistry.find("linea.test.test.category.some.metric").summary() assertThat(createdHistogram).isNotNull assertThat(createdHistogram!!.id.description).isEqualTo("This is a test metric") - assertThat(createdHistogram.id.tags).isEqualTo( - listOf(ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2")), + assertThat( + createdHistogram.id.tags, + ).containsAll( + listOf(ImmutableTag("version", "1.0.1"), ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2")), ) assertThat(createdHistogram.id.baseUnit).isEqualTo("seconds") assertThat(createdHistogram.count()).isEqualTo(0L) @@ -113,16 +131,21 @@ class MicrometerMetricsFacadeTest { val expectedTags = listOf(Tag("key1", "value1"), Tag("key2", "value2")) val timer = metricsFacade.createSimpleTimer( + category = TestCategory.TEST_CATEGORY, name = "some.timer.metric", description = "This is a test metric", tags = expectedTags, ) timer.captureTime(::mockTimer) - val createdTimer = meterRegistry.find("linea.test.some.timer.metric").timer() + val createdTimer = meterRegistry.find("linea.test.test.category.some.timer.metric").timer() assertThat(createdTimer).isNotNull assertThat(createdTimer!!.id.description).isEqualTo("This is a test metric") - assertThat(createdTimer.id.tags).isEqualTo(listOf(ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2"))) + assertThat( + createdTimer.id.tags, + ).containsAll( + listOf(ImmutableTag("version", "1.0.1"), ImmutableTag("key1", "value1"), ImmutableTag("key2", "value2")), + ) assertThat(createdTimer.max(TimeUnit.SECONDS)).isGreaterThan(0.2) timer.captureTime(::mockTimer) @@ -137,6 +160,7 @@ class MicrometerMetricsFacadeTest { } val timer = metricsFacade.createDynamicTagTimer( + category = TestCategory.TEST_CATEGORY, name = "some.dynamictag.timer.metric", description = "This is a test metric", tagKey = "key", @@ -146,10 +170,10 @@ class MicrometerMetricsFacadeTest { } timer.captureTime(::mockTimer) - val createdTimer = meterRegistry.find("linea.test.some.dynamictag.timer.metric").timer() + val createdTimer = meterRegistry.find("linea.test.test.category.some.dynamictag.timer.metric").timer() assertThat(createdTimer).isNotNull assertThat(createdTimer!!.id.description).isEqualTo("This is a test metric") - assertThat(createdTimer.id.tags).isEqualTo(listOf(ImmutableTag("key", "value"))) + assertThat(createdTimer.id.tags).containsAll(listOf(ImmutableTag("version", "1.0.1"), ImmutableTag("key", "value"))) assertThat(createdTimer.max(TimeUnit.SECONDS)).isGreaterThan(0.2) timer.captureTime(::mockTimer) @@ -163,12 +187,13 @@ class MicrometerMetricsFacadeTest { val meterRegistry = SimpleMeterRegistry() val metricsFacade = MicrometerMetricsFacade(meterRegistry) metricsFacade.createGauge( + category = TestCategory.TEST_CATEGORY, name = "some.gauge.metric", description = "This is a test metric", measurementSupplier = { metricMeasureValue }, tags = listOf(Tag("key1", "value1"), Tag("key2", "value2")), ) - val createdGauge = meterRegistry.find("some.gauge.metric").gauge() + val createdGauge = meterRegistry.find("test.category.some.gauge.metric").gauge() assertThat(createdGauge).isNotNull } @@ -177,11 +202,12 @@ class MicrometerMetricsFacadeTest { val meterRegistry = SimpleMeterRegistry() val metricsFacade = MicrometerMetricsFacade(meterRegistry) metricsFacade.createCounter( + category = TestCategory.TEST_CATEGORY, name = "some.counter.metric", description = "This is a test metric", tags = listOf(Tag("key1", "value1"), Tag("key2", "value2")), ) - val createdCounter = meterRegistry.find("some.counter.metric").counter() + val createdCounter = meterRegistry.find("test.category.some.counter.metric").counter() assertThat(createdCounter).isNotNull } @@ -190,12 +216,13 @@ class MicrometerMetricsFacadeTest { val meterRegistry = SimpleMeterRegistry() val metricsFacade = MicrometerMetricsFacade(meterRegistry) metricsFacade.createHistogram( + category = TestCategory.TEST_CATEGORY, name = "some.histogram.metric", description = "This is a test metric", tags = listOf(Tag("key1", "value1"), Tag("key2", "value2")), baseUnit = "seconds", ) - val createdHistogram = meterRegistry.find("some.histogram.metric").summary() + val createdHistogram = meterRegistry.find("test.category.some.histogram.metric").summary() assertThat(createdHistogram).isNotNull } @@ -204,12 +231,13 @@ class MicrometerMetricsFacadeTest { val meterRegistry = SimpleMeterRegistry() val metricsFacade = MicrometerMetricsFacade(meterRegistry) val timer = metricsFacade.createSimpleTimer( + category = TestCategory.TEST_CATEGORY, name = "some.timer.metric", description = "This is a test metric", tags = listOf(Tag("key1", "value1"), Tag("key2", "value2")), ) timer.captureTime {} - val createdTimer = meterRegistry.find("some.timer.metric").timer() + val createdTimer = meterRegistry.find("test.category.some.timer.metric").timer() assertThat(createdTimer).isNotNull } @@ -218,6 +246,7 @@ class MicrometerMetricsFacadeTest { val meterRegistry = SimpleMeterRegistry() val metricsFacade = MicrometerMetricsFacade(meterRegistry) val timer = metricsFacade.createDynamicTagTimer( + category = TestCategory.TEST_CATEGORY, name = "some.dynamictag.timer.metric", description = "This is a test metric", tagKey = "key", @@ -226,7 +255,7 @@ class MicrometerMetricsFacadeTest { "value" } timer.captureTime {} - val createdTimer = meterRegistry.find("some.dynamictag.timer.metric").timer() + val createdTimer = meterRegistry.find("test.category.some.dynamictag.timer.metric").timer() assertThat(createdTimer).isNotNull } } diff --git a/transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/metrics/LineaMetricsCategory.kt b/transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/metrics/LineaMetricsCategory.kt new file mode 100644 index 00000000..6ac7f683 --- /dev/null +++ b/transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/metrics/LineaMetricsCategory.kt @@ -0,0 +1,7 @@ +package net.consensys.linea.transactionexclusion.metrics + +import net.consensys.linea.metrics.MetricsCategory + +enum class LineaMetricsCategory : MetricsCategory { + TX_EXCLUSION_API, +} diff --git a/transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/service/TransactionExclusionServiceV1Impl.kt b/transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/service/TransactionExclusionServiceV1Impl.kt index cc336e40..f4c61e81 100644 --- a/transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/service/TransactionExclusionServiceV1Impl.kt +++ b/transaction-exclusion-api/app/src/main/kotlin/net/consensys/linea/transactionexclusion/service/TransactionExclusionServiceV1Impl.kt @@ -4,13 +4,13 @@ import com.github.michaelbull.result.Err import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Result import kotlinx.datetime.Clock -import net.consensys.linea.metrics.LineaMetricsCategory import net.consensys.linea.metrics.MetricsFacade import net.consensys.linea.transactionexclusion.ErrorType import net.consensys.linea.transactionexclusion.RejectedTransaction import net.consensys.linea.transactionexclusion.TransactionExclusionError import net.consensys.linea.transactionexclusion.TransactionExclusionServiceV1 import net.consensys.linea.transactionexclusion.TransactionExclusionServiceV1.SaveRejectedTransactionStatus +import net.consensys.linea.transactionexclusion.metrics.LineaMetricsCategory import net.consensys.zkevm.persistence.dao.rejectedtransaction.RejectedTransactionsDao import net.consensys.zkevm.persistence.db.DuplicatedRecordException import tech.pegasys.teku.infrastructure.async.SafeFuture