Skip to content

Commit 62177a1

Browse files
committed
Improve documentation for Spring Boot's OpenTelemetry support
Closes gh-47960
1 parent 49d72c2 commit 62177a1

File tree

4 files changed

+124
-10
lines changed

4 files changed

+124
-10
lines changed

documentation/spring-boot-docs/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ dependencies {
151151
implementation("io.micrometer:micrometer-registry-graphite")
152152
implementation("io.micrometer:micrometer-registry-jmx")
153153
implementation("io.opentelemetry.instrumentation:opentelemetry-logback-appender-1.0")
154+
implementation("io.opentelemetry:opentelemetry-sdk-metrics")
155+
implementation("io.opentelemetry:opentelemetry-exporter-otlp")
154156
implementation("io.projectreactor.netty:reactor-netty-http")
155157
implementation("jakarta.annotation:jakarta.annotation-api")
156158
implementation("jakarta.jms:jakarta.jms-api")

documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/observability.adoc

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ The preceding example will prevent all observations whose name contains "denied"
8282

8383

8484

85+
[[actuator.observability.annotations]]
86+
== Micrometer Observation Annotations support
87+
88+
To enable scanning of observability annotations like javadoc:io.micrometer.observation.annotation.Observed[format=annotation], javadoc:io.micrometer.core.annotation.Timed[format=annotation], javadoc:io.micrometer.core.annotation.Counted[format=annotation], javadoc:io.micrometer.core.aop.MeterTag[format=annotation] and javadoc:io.micrometer.tracing.annotation.NewSpan[format=annotation], you need to set the configprop:management.observations.annotations.enabled[] property to `true`.
89+
This feature is supported by Micrometer directly.
90+
Please refer to the {url-micrometer-docs-concepts}/timers.html#_the_timed_annotation[Micrometer], {url-micrometer-docs-observation}/components.html#micrometer-observation-annotations[Micrometer Observation] and {url-micrometer-tracing-docs}/api.html#_aspect_oriented_programming[Micrometer Tracing] reference docs.
91+
92+
NOTE: When you annotate methods or classes which are already instrumented (for example, xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-data-repository[Spring Data repositories] or xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-mvc[Spring MVC controllers]), you will get duplicate observations.
93+
In that case you can either disable the automatic instrumentation using xref:reference:actuator/observability.adoc#actuator.observability.preventing-observations[properties] or an javadoc:io.micrometer.observation.ObservationPredicate[] and rely on your annotations, or you can remove your annotations.
94+
95+
96+
8597
[[actuator.observability.opentelemetry]]
8698
== OpenTelemetry Support
8799

@@ -101,24 +113,72 @@ Auto-configured attributes will be merged with attributes from the `OTEL_RESOURC
101113

102114
If you have defined your own javadoc:io.opentelemetry.sdk.resources.Resource[] bean, this will no longer be the case.
103115

104-
NOTE: Spring Boot does not provide auto-configuration for OpenTelemetry metrics or logging.
105-
OpenTelemetry tracing is only auto-configured when used together with xref:actuator/tracing.adoc[Micrometer Tracing].
116+
NOTE: Spring Boot does not provide automatic exporting of OpenTelemetry metrics or logs.
117+
Exporting OpenTelemetry traces is only auto-configured when used together with xref:actuator/tracing.adoc[Micrometer Tracing].
118+
119+
120+
121+
[[actuator.observability.opentelemetry.environment-variables]]
122+
=== Environment variables
123+
124+
Spring Boot supports the following environment variables to configure the OpenTelemetry resource:
125+
126+
* https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration[`OTEL_RESOURCE_ATTRIBUTES`]
127+
* https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration[`OTEL_SERVICE_NAME`]
106128

107129
NOTE: The `OTEL_RESOURCE_ATTRIBUTES` environment variable consists of a list of key-value pairs.
108130
For example: `key1=value1,key2=value2,key3=spring%20boot`.
109131
All attribute values are treated as strings, and any characters outside the baggage-octet range must be **percent-encoded**.
110132

133+
Micrometer also supports the following environment variables to configure the metrics export over OTLP:
111134

112-
The next sections will provide more details about logging, metrics and traces.
135+
* https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_endpoint[`OTEL_EXPORTER_OTLP_ENDPOINT`]
136+
* https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_metrics_endpoint[`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`]
137+
* https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_headers[`OTEL_EXPORTER_OTLP_HEADERS`]
138+
* https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_metrics_headers[`OTEL_EXPORTER_OTLP_METRICS_HEADERS`]
113139

140+
Logging and tracing use the OpenTelemetry SDK directly, so all environment variables https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/[supported by OpenTelemetry] also work.
114141

142+
[[actuator.observability.opentelemetry.logging]]
143+
=== Logging
115144

116-
[[actuator.observability.annotations]]
117-
== Micrometer Observation Annotations support
145+
The javadoc:org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingAutoConfiguration[] configures OpenTelemetry's javadoc:io.opentelemetry.sdk.logs.SdkLoggerProvider[].
146+
Exporting logs via OTLP is supported through the javadoc:org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration[], which enables OTLP log exporting over HTTP or gRPC.
118147

119-
To enable scanning of observability annotations like javadoc:io.micrometer.observation.annotation.Observed[format=annotation], javadoc:io.micrometer.core.annotation.Timed[format=annotation], javadoc:io.micrometer.core.annotation.Counted[format=annotation], javadoc:io.micrometer.core.aop.MeterTag[format=annotation] and javadoc:io.micrometer.tracing.annotation.NewSpan[format=annotation], you need to set the configprop:management.observations.annotations.enabled[] property to `true`.
120-
This feature is supported by Micrometer directly.
121-
Please refer to the {url-micrometer-docs-concepts}/timers.html#_the_timed_annotation[Micrometer], {url-micrometer-docs-observation}/components.html#micrometer-observation-annotations[Micrometer Observation] and {url-micrometer-tracing-docs}/api.html#_aspect_oriented_programming[Micrometer Tracing] reference docs.
148+
However, while there is a `SdkLoggerProvider` bean, Spring Boot doesn't support bridging logs to this bean out of the box.
149+
This can be done with 3rd-party log bridges, as described in the xref:reference:actuator/loggers.adoc#actuator.loggers.opentelemetry[Logging with OpenTelemetry] section.
122150

123-
NOTE: When you annotate methods or classes which are already instrumented (for example, xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-data-repository[Spring Data repositories] or xref:reference:actuator/metrics.adoc#actuator.metrics.supported.spring-mvc[Spring MVC controllers]), you will get duplicate observations.
124-
In that case you can either disable the automatic instrumentation using xref:reference:actuator/observability.adoc#actuator.observability.preventing-observations[properties] or an javadoc:io.micrometer.observation.ObservationPredicate[] and rely on your annotations, or you can remove your annotations.
151+
152+
153+
[[actuator.observability.opentelemetry.metrics]]
154+
=== Metrics
155+
156+
The choice of metrics in the Spring portfolio is Micrometer, which means that metrics are not collected and exported through the OpenTelemetry's javadoc:io.opentelemetry.sdk.metrics.SdkMeterProvider[].
157+
Spring Boot doesn't provide a `SdkMeterProvider` bean.
158+
159+
160+
However, Micrometer metrics can be exported via OTLP to any OpenTelemetry capable backend using the javadoc:io.micrometer.registry.otlp.OtlpMeterRegistry[], as described in the xref:reference:actuator/metrics.adoc#actuator.metrics.export.otlp[Metrics with OTLP] section.
161+
162+
NOTE: Micrometer's OTLP registry doesn't use the `Resource` bean, but setting `OTEL_RESOURCE_ATTRIBUTES`, `OTEL_SERVICE_NAME` or configprop:management.opentelemetry.resource-attributes[] works.
163+
164+
[[actuator.observability.opentelemetry.metrics.api-and-sdk]]
165+
==== Metrics via the OpenTelemetry API and SDK
166+
167+
If you or a dependency you include make use of OpenTelemetry's javadoc:io.opentelemetry.api.metrics.MeterProvider[], those metrics are not exported.
168+
169+
We strongly recommend that you report your metrics with Micrometer.
170+
If a dependency you include uses OpenTelemetry's `MeterProvider`, you can include this configuration in your application to configure a `MeterProvider` bean, which you then have to wire into your dependency:
171+
172+
include-code::OpenTelemetryMetricsConfiguration[]
173+
174+
This configuration also enables metrics export via OTLP over HTTP.
175+
176+
177+
178+
[[actuator.observability.opentelemetry.tracing]]
179+
=== Tracing
180+
181+
If Micrometer tracing is used, the javadoc:org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.OpenTelemetryTracingAutoConfiguration[] configures OpenTelemetry's javadoc:io.opentelemetry.sdk.trace.SdkTracerProvider[].
182+
Exporting traces through OTLP is enabled by the javadoc:org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.otlp.OtlpTracingAutoConfiguration[], which supports exporting traces with OTLP over HTTP or gRPC.
183+
184+
We strongly recommend using the Micrometer Observation or Tracing API instead of using the OpenTelemetry API directly.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.docs.actuator.observability.opentelemetry.metrics.apiandsdk;
18+
19+
import java.time.Duration;
20+
21+
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
22+
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
23+
import io.opentelemetry.sdk.metrics.export.MetricExporter;
24+
import io.opentelemetry.sdk.metrics.export.MetricReader;
25+
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
26+
import io.opentelemetry.sdk.resources.Resource;
27+
28+
import org.springframework.context.annotation.Bean;
29+
import org.springframework.context.annotation.Configuration;
30+
31+
@Configuration(proxyBeanMethods = false)
32+
class OpenTelemetryMetricsConfiguration {
33+
34+
@Bean
35+
OtlpHttpMetricExporter metricExporter() {
36+
String endpoint = "http://localhost:4318/v1/metrics";
37+
return OtlpHttpMetricExporter.builder().setEndpoint(endpoint).build();
38+
}
39+
40+
@Bean
41+
PeriodicMetricReader metricReader(MetricExporter exporter) {
42+
Duration interval = Duration.ofMinutes(1);
43+
return PeriodicMetricReader.builder(exporter).setInterval(interval).build();
44+
}
45+
46+
@Bean
47+
SdkMeterProvider meterProvider(Resource resource, MetricReader metricReader) {
48+
return SdkMeterProvider.builder().registerMetricReader(metricReader).setResource(resource).build();
49+
}
50+
51+
}

platform/spring-boot-dependencies/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,7 @@ bom {
15481548
javadoc("micrometer-core", version -> "https://javadoc.io/doc/io.micrometer/micrometer-core/%s".formatted(version), "io.micrometer.core")
15491549
javadoc("micrometer-observation", version -> "https://javadoc.io/doc/io.micrometer/micrometer-observation/%s".formatted(version), "io.micrometer.observation")
15501550
javadoc("micrometer-registry-graphite", version -> "https://javadoc.io/doc/io.micrometer/micrometer-registry-graphite/%s".formatted(version), "io.micrometer.graphite")
1551+
javadoc("micrometer-registry-otlp", version -> "https://javadoc.io/doc/io.micrometer/micrometer-registry-otlp/%s".formatted(version), "io.micrometer.registry.otlp")
15511552
javadoc("micrometer-registry-jmx", version -> "https://javadoc.io/doc/io.micrometer/micrometer-registry-jmx/%s".formatted(version), "io.micrometer.jmx")
15521553
javadoc("micrometer-new-relic", version -> "https://javadoc.io/doc/io.micrometer/micrometer-registry-new-relic/%s".formatted(version), "io.micrometer.newrelic")
15531554
docs(version -> "https://docs.micrometer.io/micrometer/reference/%s.%s"

0 commit comments

Comments
 (0)