From 73b8d372a3511cba71e20a466b0b77bd07eecfb3 Mon Sep 17 00:00:00 2001 From: brunobat Date: Thu, 9 Jan 2025 19:07:55 +0000 Subject: [PATCH] Docs --- ...telemetry-micrometer-to-opentelemetry.adoc | 110 +++++++++++++++++- .../deployment/DistributionSummaryTest.java | 2 +- .../src/main/resources/application.properties | 3 + 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 extensions/micrometer-opentelemetry/runtime/src/main/resources/application.properties diff --git a/docs/src/main/asciidoc/telemetry-micrometer-to-opentelemetry.adoc b/docs/src/main/asciidoc/telemetry-micrometer-to-opentelemetry.adoc index 4f6644e06c735a..a5cd80f3ecd3f5 100644 --- a/docs/src/main/asciidoc/telemetry-micrometer-to-opentelemetry.adoc +++ b/docs/src/main/asciidoc/telemetry-micrometer-to-opentelemetry.adoc @@ -20,12 +20,14 @@ This extension provides support for both `Micrometer` and `OpenTelemetry` in Qua - The xref:opentelemetry.adoc[OpenTelemetry Guide] provides information about the OpenTelemetry extension. ==== -The bridge is much more than the simple OTLP registry found in Quarkiverse. In this extension, the OpenTelemetry SDK provides a Micrometer registry implementation. +The bridge is more than the simple OTLP registry found in Quarkiverse. In this extension, the OpenTelemetry SDK provides a Micrometer registry implementation. This allows the normal use of the Micrometer API, but have the metrics handled by the OpenTelemetry extension. All the configurations of the OpenTelemetry extension are available for this bridge. The bridge enables to forward to OpenTelemetry all the automatic instrumentation metrics generated by Micrometer in Quarkus, as well as custom user metrics. +The bridge is based on the https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/micrometer/micrometer-1.5/library[`micrometer/micrometer-1.5`] OpenTelemetry instrumentation library. + == Usage If you already have your Quarkus project configured, you can add the `quarkus-micrometer-opentelemetry` extension to your project by running the following command in your project base directory: @@ -50,4 +52,110 @@ This will add the following to your build file: implementation("io.quarkus:quarkus-micrometer-opentelemetry") ---- +== Metric differences between Micrometer and OpenTelemetry + +=== API differences +The metrics produced with each framework follow different APIs and the mapping is not 1:1. + +One fundamental API difference is that Micrometer uses a https://docs.micrometer.io/micrometer/reference/concepts/timers.html[Timer] and OpenTelemetry uses a https://opentelemetry.io/docs/specs/otel/metrics/data-model/#histogram[Histogram] to record latency (execution time) metrics and the frequency of the events. + +When using the `Timed` with Micrometer, 2 different metrics are https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/324fdbdd452ddffaf2da2c5bf004d8bb3fdfa1dd/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryTimer.java#L31[created on the OpenTelemetry side], one `Gauge` for the `max` value and one `Histogram`. + +The `DistributionSummary` from Micrometer is transformed into a `histogram` represented by a `DoubleGauge' with data points matching the buckets, another `DoubleGauge` for the `max` value and finally an actually OpenTelemetry `Histogram`. There is data duplication that might be optimized in the future. + +|=== +|Micrometer |OpenTelemetry + +|DistributionSummary +|`` (Histogram), `.max` (DoubleGauge) + +|DistributionSummary with SLOs +|`` (Histogram), `.max` (DoubleGauge), `.histogram` (DoubleGauge) + +|LongTaskTimer +|`.active` (ObservableLongUpDownCounter), `.duration` (ObservableDoubleUpDownCounter) + +|Timer +|`` (Histogram), `.max` (ObservableDoubleGauge) +|=== + + + +=== Semantic convention differences + +The following table shows some differences between the two frameworks. This list is not exhaustive and only shows some examples, for reference. + +When `quarkus.micrometer.binder.jvm=true` is set, the JVM metrics are collected by Micrometer. Here we show a subset related with `Threads`. + + +|=== +|Micrometer Meter |Quarkus Micrometer Prometheus output | This bridge OpenTelemetry output name | Related OpenTelemetry Semantic Convention (not applied) + +|Using the @Timed interceptor. +| +|method.timed (Histogram), method.timed.max (DoubleGauge) +|NA + +|Using the @Counted interceptor. +| +|method.counted (DoubleSum) +|NA + +|`http.server.active.requests` (Gauge) +|`http_server_active_requests` (Gauge) +|`http.server.active.requests` (DoubleGauge) +|https://opentelemetry.io/docs/specs/semconv/http/http-metrics/#metric-httpserveractive_requests[`http.server.active_requests`] (UpDownCounter) + +|`http.server.requests` (Timer) +|`http_server_requests_seconds_count`, `http_server_requests_seconds_sum`, `http_server_requests_seconds_max` (Gauge) +|`http.server.requests` (Histogram), `http.server.requests.max` (DoubleGauge) +|https://opentelemetry.io/docs/specs/semconv/http/http-metrics/#metric-httpserverrequestduration[`http.server.request.duration`] (Histogram) + +|`http.server.bytes.read` (DistributionSummary) +|`http_server_bytes_read_count`, `http_server_bytes_read_sum` , `http_server_bytes_read_max` (Gauge) +|`http.server.bytes.read` (Histogram), `http.server.bytes.read.max` (DoubleGauge) +|https://opentelemetry.io/docs/specs/semconv/http/http-metrics/#metric-httpserverrequestbodysize[`http.server.request.body.size`] (Histogram) + +|`http.server.bytes.write` (DistributionSummary) +|`http_server_bytes_write_count`, `http_server_bytes_write_sum` , `http_server_bytes_write_max` (Gauge) +|`http.server.bytes.write` (Histogram), `http.server.bytes.write.max` (DoubleGauge) +|https://opentelemetry.io/docs/specs/semconv/http/http-metrics/#metric-httpserverresponsebodysize[`http.server.response.body.size`] (Histogram) + +|`http.server.connections` (LongTaskTimer) +|`http_server_connections_seconds_active_count`, `http_server_connections_seconds_duration_sum` `http_server_connections_seconds_max` (Gauge) +|`http.server.connections.active` (LongSum), `http.server.connections.duration` (DoubleGauge) +| N/A + +|`jvm.threads.live` (Gauge) +|`jvm_threads_live_threads` (Gauge) +|`jvm.threads.live` (DoubleGauge) +|https://opentelemetry.io/docs/specs/semconv/runtime/jvm-metrics/#metric-jvmthreadcount[`jvm.threads.live`] (UpDownCounter) + +|`jvm.threads.started` (FunctionCounter) +|`jvm_threads_started_threads_total` (Counter) +|`jvm.threads.started` (DoubleSum) +|https://opentelemetry.io/docs/specs/semconv/runtime/jvm-metrics/#metric-jvmthreadcount[`jvm.threads.live`] (UpDownCounter) + +|`jvm.threads.daemon` (Gauge) +|`jvm_threads_daemon_threads` (Gauge) +|`jvm.threads.daemon` (DoubleGauge) +|https://opentelemetry.io/docs/specs/semconv/runtime/jvm-metrics/#metric-jvmthreadcount[`jvm.threads.live`] (UpDownCounter) + +|`jvm.threads.peak` (Gauge) +|`jvm_threads_peak_threads` (Gauge) +|`jvm.threads.peak` (DoubleGauge) +|N/A + +|`jvm.threads.states` (Gauge per state) +|`jvm_threads_states_threads` (Gauge) +|`jvm.threads.states` (DoubleGauge) +|https://opentelemetry.io/docs/specs/semconv/runtime/jvm-metrics/#metric-jvmthreadcount[`jvm.threads.live`] (UpDownCounter) +|=== + + +[NOTE] +==== +- Some metrics might be absent of the output if they contain no data. +==== +== See output diff --git a/extensions/micrometer-opentelemetry/deployment/src/test/java/io/quarkus/micrometer/opentelemetry/deployment/DistributionSummaryTest.java b/extensions/micrometer-opentelemetry/deployment/src/test/java/io/quarkus/micrometer/opentelemetry/deployment/DistributionSummaryTest.java index aa33ba4fcbcc9d..a3dcf1f7fb01f1 100644 --- a/extensions/micrometer-opentelemetry/deployment/src/test/java/io/quarkus/micrometer/opentelemetry/deployment/DistributionSummaryTest.java +++ b/extensions/micrometer-opentelemetry/deployment/src/test/java/io/quarkus/micrometer/opentelemetry/deployment/DistributionSummaryTest.java @@ -77,7 +77,7 @@ void histogramTest() { .hasValue(500) .hasAttributes(attributeEntry("tag", "value")))); - MetricData testSummaryHistogram = exporter.getFinishedMetricItem("testSummary.histogram"); + MetricData testSummaryHistogram = exporter.getFinishedMetricItem("testSummary.histogram"); // present when SLOs are set assertNotNull(testSummaryHistogram); assertThat(testSummaryHistogram) .hasDoubleGaugeSatisfying( diff --git a/extensions/micrometer-opentelemetry/runtime/src/main/resources/application.properties b/extensions/micrometer-opentelemetry/runtime/src/main/resources/application.properties new file mode 100644 index 00000000000000..b91ad1c930a64d --- /dev/null +++ b/extensions/micrometer-opentelemetry/runtime/src/main/resources/application.properties @@ -0,0 +1,3 @@ +# Don't instrument with OTel +quarkus.otel.instrument.http-server-metrics=false +quarkus.otel.instrument.jvm-metrics=false \ No newline at end of file