Add global labels to the OpenTelemetry metrics implementation [PLEN-5] (#15407)

This commit is contained in:
Nicu Reut 2022-11-01 16:28:53 +01:00 committed by GitHub
parent 7ab367b0e3
commit 7077a4dce1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 6 deletions

View File

@ -24,6 +24,7 @@ da_scala_library(
runtime_deps = [],
deps = [
"//ledger/ledger-resources",
"//libs-scala/build-info",
"//libs-scala/concurrent",
"//libs-scala/resources",
"//libs-scala/resources-akka",

View File

@ -15,6 +15,8 @@ case class MetricsContext(labels: Map[String, String]) {
.build()
}
def merge(context: MetricsContext): MetricsContext = this.copy(labels = labels ++ context.labels)
}
object MetricsContext {

View File

@ -6,6 +6,7 @@ package com.daml.metrics.api.opentelemetry
import java.time.Duration
import java.util.concurrent.TimeUnit
import com.daml.buildinfo.BuildInfo
import com.daml.metrics.api.Gauges.VarGauge
import com.daml.metrics.api.MetricHandle.Timer.TimerHandle
import com.daml.metrics.api.MetricHandle.{Counter, Factory, Gauge, Histogram, Meter, Timer}
@ -20,7 +21,12 @@ import io.opentelemetry.api.metrics.{
trait OpenTelemetryFactory extends Factory {
val globalMetricsContext: MetricsContext = MetricsContext(
Map("daml_version" -> BuildInfo.Version)
)
def otelMeter: OtelMeter
override def timer(
name: MetricName
)(implicit
@ -29,12 +35,12 @@ trait OpenTelemetryFactory extends Factory {
OpentelemetryTimer(
name,
otelMeter.histogramBuilder(name).ofLongs().setUnit("ms").build(),
context,
globalMetricsContext.merge(context),
)
override def gauge[T](name: MetricName, initial: T)(implicit
context: MetricsContext = MetricsContext.Empty
): MetricHandle.Gauge[T] = {
val attributes = context.asAttributes
val attributes = globalMetricsContext.merge(context).asAttributes
initial match {
case longInitial: Int =>
val varGauge = new VarGauge[Int](longInitial)
@ -67,7 +73,7 @@ trait OpenTelemetryFactory extends Factory {
context: MetricsContext = MetricsContext.Empty
): Unit = {
val value = valueSupplier()
val attributes = context.asAttributes
val attributes = globalMetricsContext.merge(context).asAttributes
value match {
case _: Int =>
otelMeter
@ -104,21 +110,21 @@ trait OpenTelemetryFactory extends Factory {
): Meter = OpentelemetryMeter(
name,
otelMeter.counterBuilder(name).build(),
context,
globalMetricsContext.merge(context),
)
override def counter(name: MetricName)(implicit
context: MetricsContext = MetricsContext.Empty
): MetricHandle.Counter = OpentelemetryCounter(
name,
otelMeter.upDownCounterBuilder(name).build(),
context,
globalMetricsContext.merge(context),
)
override def histogram(name: MetricName)(implicit
context: MetricsContext = MetricsContext.Empty
): MetricHandle.Histogram = OpentelemetryHistogram(
name,
otelMeter.histogramBuilder(name).ofLongs().build(),
context,
globalMetricsContext.merge(context),
)
}

View File

@ -0,0 +1,47 @@
// Copyright (c) 2022 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.metrics.api
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
class MetricsContextSpec extends AnyWordSpec with Matchers {
"merging metrics contexts" should {
"merge all labels" in {
MetricsContext(
Map("key" -> "value")
).merge(
MetricsContext(
Map("key2" -> "value")
)
) should equal(
MetricsContext(
Map(
"key" -> "value",
"key2" -> "value",
)
)
)
}
"handle duplicate labels" in {
MetricsContext(
Map("key" -> "value1")
).merge(
MetricsContext(
Map("key" -> "value2")
)
) should equal(
MetricsContext(
Map(
"key" -> "value2"
)
)
)
}
}
}