11# Spring Boot Declarative Configuration Example
22
3- This example demonstrates how to use [ declarative configuration] ( https://opentelemetry.io/docs/specs/otel/configuration/#declarative-configuration )
4- with the OpenTelemetry Spring Boot Starter to configure tracing, metrics, and logging for a Spring Boot application.
3+ This example demonstrates how to
4+ use [ declarative configuration] ( https://opentelemetry.io/docs/specs/otel/configuration/#declarative-configuration )
5+ with the OpenTelemetry Spring Boot Starter to configure tracing, metrics, and logging for a Spring
6+ Boot application.
57
6- Instead of using the OpenTelemetry Java Agent and an ` otel-agent-config.yaml ` file , this module uses the
8+ Instead of using the OpenTelemetry Java Agent, this module uses the
79[ OpenTelemetry Spring Boot Starter] ( https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/spring/spring-boot-autoconfigure )
810and configures declarative behavior via standard Spring Boot configuration in ` application.yaml ` .
911
10- > ** Requirement:** Declarative configuration via the Spring Boot Starter requires version ** 2.22.0 or newer** of the
12+ > ** Requirement:** Declarative configuration via the Spring Boot Starter requires version ** 2.22.0
13+ or newer** of the
1114> OpenTelemetry Spring Boot Starter.
1215
1316The main configuration file for this example is:
1417
1518- [ ` src/main/resources/application.yaml ` ] ( ./src/main/resources/application.yaml )
1619
1720For the underlying declarative configuration schema and additional examples, see the
18- [ opentelemetry-configuration] ( https://github.com/open-telemetry/opentelemetry-configuration ) repository.
19- Remember that when you copy examples from that repository into a Spring Boot app, you must nest them under the
21+ [ opentelemetry-configuration] ( https://github.com/open-telemetry/opentelemetry-configuration )
22+ repository.
23+ Remember that when you copy examples from that repository into a Spring Boot app, you must nest them
24+ under the
2025` otel: ` root node (two-space indentation for all keys shown below).
2126
2227This Spring Boot application includes two endpoints:
2328
24- - ` /actuator/health ` – A health check endpoint (from Spring Boot Actuator) that is configured to be ** excluded** from tracing
29+ - ` /actuator/health ` – A health check endpoint (from Spring Boot Actuator) that is configured to be
30+ ** excluded** from tracing
2531- ` /api/example ` – A simple API endpoint that ** will be traced** normally
2632
2733## End-to-End Instructions
2834
2935### Prerequisites
3036
3137- Java 17 or higher
32- - OpenTelemetry Spring Boot Starter ** 2.22.0+** on the classpath of this application (already configured in this
38+ - OpenTelemetry Spring Boot Starter ** 2.22.0+** on the classpath of this application (already
39+ configured in this
3340 example’s build files)
3441
3542### Step 1: Build the Application
@@ -44,8 +51,10 @@ This builds the Spring Boot fat JAR for the example application.
4451
4552### Step 2: Run the Spring Boot Application
4653
47- Run the application as a normal Spring Boot JAR – no ` -javaagent ` flag and no separate ` otel-agent-config.yaml ` file
48- are needed. Declarative configuration is picked up from ` application.yaml ` by the Spring Boot Starter.
54+ Run the application as a normal Spring Boot JAR – no ` -javaagent ` flag and no separate
55+ ` otel-agent-config.yaml ` file
56+ are needed. Declarative configuration is picked up from ` application.yaml ` by the Spring Boot
57+ Starter.
4958
5059``` bash
5160java -jar build/libs/spring-declarative-configuration.jar
@@ -81,31 +90,36 @@ Check the application logs to see that:
8190- Health check requests (` /actuator/health ` ) ** do not** generate spans (dropped by sampler rules)
8291- Requests to ` /api/example ` ** do** generate spans and are exported to console and/or OTLP
8392
84- If you have an OTLP-compatible backend (e.g., the OpenTelemetry Collector, Jaeger, Tempo, etc.) listening on
93+ If you have an OTLP-compatible backend (e.g., the OpenTelemetry Collector, Jaeger, Tempo, etc.)
94+ listening on
8595` http://localhost:4318 ` , you can inspect the exported telemetry there as well.
8696
8797## Declarative Configuration with Spring Boot
8898
89- The declarative configuration used by this example lives in [ ` application.yaml ` ] ( ./src/main/resources/application.yaml )
99+ The declarative configuration used by this example lives in [
100+ ` application.yaml ` ] ( ./src/main/resources/application.yaml )
90101under the ` otel: ` root key.
91102
92103``` yaml
93104otel :
94- # ... see src/main/resources/application.yaml for the full configuration
105+ # ... see src/main/resources/application.yaml for the full configuration
95106```
96107
97108This layout follows the declarative configuration schema defined in the
98- [ opentelemetry-configuration] ( https://github.com/open-telemetry/opentelemetry-configuration ) repository, but adapted
109+ [ opentelemetry-configuration] ( https://github.com/open-telemetry/opentelemetry-configuration )
110+ repository, but adapted
99111for Spring Boot:
100112
101113- All OpenTelemetry configuration keys live under the ` otel: ` root
102- - Configuration blocks from the reference repo (such as ` tracer_provider ` , ` meter_provider ` , ` logger_provider ` , etc.)
114+ - Configuration blocks from the reference repo (such as ` tracer_provider ` , ` meter_provider ` ,
115+ ` logger_provider ` , etc.)
103116 are indented by ** two spaces** beneath ` otel: `
104117- The configuration is loaded via the OpenTelemetry Spring Boot Starter instead of the Java Agent
105118
106119### Opting In with ` file_format `
107120
108- Declarative configuration is ** opt-in** . In this Spring Boot example, you enable declarative configuration by setting
121+ Declarative configuration is ** opt-in** . In this Spring Boot example, you enable declarative
122+ configuration by setting
109123` file_format ` under ` otel: ` in ` application.yaml ` :
110124
111125``` yaml
@@ -120,7 +134,8 @@ If `file_format` is missing, declarative configuration is not applied.
120134
121135### Example: Exporters and Sampler Rules (Spring Style)
122136
123- Below is a simplified view of the configuration used in this module. All keys are indented under ` otel: ` as required by
137+ Below is a simplified view of the configuration used in this module. All keys are indented under
138+ ` otel: ` as required by
124139Spring Boot declarative configuration. Refer to the actual
125140[ ` application.yaml ` ] ( ./src/main/resources/application.yaml ) for the complete version.
126141
@@ -175,7 +190,8 @@ otel:
175190 endpoint : ${OTEL_EXPORTER_OTLP_ENDPOINT:http://localhost:4318}/v1/logs
176191` ` `
177192
178- This configuration is conceptually equivalent to the Java Agent example’s ` rule_based_routing` sampler (from
193+ This configuration is conceptually equivalent to the Java Agent example’s ` rule_based_routing`
194+ sampler (from
179195`javaagent-declarative-configuration/otel-agent-config.yaml`) :
180196
181197- It uses the `rule_based_routing` sampler contribution
@@ -187,18 +203,22 @@ This configuration is conceptually equivalent to the Java Agent example’s `rul
187203
188204# ## Spring Boot Starter Version
189205
190- - Declarative configuration is supported by the OpenTelemetry Spring Boot Starter starting with version **2.22.0**
191- - Ensure your dependencies use at least this version; otherwise, `file_format` and other declarative config features
206+ - Declarative configuration is supported by the OpenTelemetry Spring Boot Starter starting with
207+ version **2.22.0**
208+ - Ensure your dependencies use at least this version; otherwise, `file_format` and other declarative
209+ config features
192210 may be ignored
193211
194212# ## Property Metadata and IDE Auto-Completion
195213
196- Most IDEs derive auto-completion for Spring properties from Spring Boot configuration metadata. At the time of this
214+ Most IDEs derive auto-completion for Spring properties from Spring Boot configuration metadata. At
215+ the time of this
197216example, that metadata is primarily based on the **non-declarative** configuration schema.
198217
199218As a result :
200219
201- - Auto-suggested properties in IDEs may be incomplete or incorrect for declarative configuration under `otel:`
220+ - Auto-suggested properties in IDEs may be incomplete or incorrect for declarative configuration
221+ under `otel:`
202222- Some declarative configuration keys may not appear in auto-completion at all
203223
204224When in doubt :
@@ -209,7 +229,8 @@ When in doubt:
209229
210230# ## Placeholder Default Values: `:` vs `:-`
211231
212- Spring Boot’s property placeholder syntax differs slightly from generic examples you might see in OpenTelemetry docs.
232+ Spring Boot’s property placeholder syntax differs slightly from generic examples you might see in
233+ OpenTelemetry docs.
213234
214235- Generic examples sometimes use `${VAR_NAME:-default}` for default values
215236- **Spring Boot uses `:` instead of `:-`**
@@ -232,45 +253,54 @@ When copying configuration from non-Spring examples, always convert `:-` to `:`
232253
233254# # Declarative vs Programmatic Configuration
234255
235- Declarative configuration, as used in this example, allows you to express routing and sampling rules entirely in
256+ Declarative configuration, as used in this example, allows you to express routing and sampling rules
257+ entirely in
236258configuration files. This is ideal for :
237259
238260- Operational teams that need to adjust sampling or filtering without changing code
239- - Environments where configuration is managed externally (Kubernetes ConfigMaps, Spring Cloud Config, etc.)
261+ - Environments where configuration is managed externally (Kubernetes ConfigMaps, Spring Cloud
262+ Config, etc.)
240263
241- For more advanced or dynamic scenarios, you can still use **programmatic** configuration. The `spring-native` module in
264+ For more advanced or dynamic scenarios, you can still use **programmatic** configuration. The
265+ ` spring-native` module in
242266this repository contains an example of this :
243267
244268- See `configureSampler` in
245- [`OpenTelemetryConfig`](../spring-native/src/main/java/io/opentelemetry/example/graal/OpenTelemetryConfig.java)
246- - It uses `RuleBasedRoutingSampler` programmatically to drop spans for actuator endpoints (`/actuator*`), replicating
269+ [
270+ ` OpenTelemetryConfig` ](../spring-native/src/main/java/io/opentelemetry/example/graal/OpenTelemetryConfig.java)
271+ - It uses `RuleBasedRoutingSampler` programmatically to drop spans for actuator endpoints (
272+ ` /actuator*` ), replicating
247273 the behavior we achieve declaratively via YAML in this module
248274
249- In many cases, you can start with declarative configuration (as in this module) and only fall back to programmatic
275+ In many cases, you can start with declarative configuration (as in this module) and only fall back
276+ to programmatic
250277customization for highly dynamic or application-specific logic.
251278
252279# # Troubleshooting and Tips
253280
254281If the behavior is not what you expect, here are a few things to check :
255282
256283- **Health checks are still traced**
257- - Verify the `rules` section under `otel.tracer_provider.sampler.rule_based_routing` in `application.yaml`
258- - Ensure the `pattern` matches your actual actuator paths (e.g., `/actuator.*`)
259- - Confirm that `span_kind` is set to `SERVER` (or another correct span kind for your traffic)
284+ - Verify the `rules` section under `otel.tracer_provider.sampler.rule_based_routing` in
285+ ` application.yaml`
286+ - Ensure the `pattern` matches your actual actuator paths (e.g., `/actuator.*`)
287+ - Confirm that `span_kind` is set to `SERVER` (or another correct span kind for your traffic)
260288
261289- **No spans are exported**
262- - Confirm that `otel.file_format` is set correctly (for example, `"1.0-rc.2"`)
263- - Check that at least one exporter is configured (e.g., `otlp_http` or `console`)
264- - Look for startup warnings or errors related to OpenTelemetry configuration
290+ - Confirm that `otel.file_format` is set correctly (for example, `"1.0-rc.2"`)
291+ - Check that at least one exporter is configured (e.g., `otlp_http` or `console`)
292+ - Look for startup warnings or errors related to OpenTelemetry configuration
265293
266294- **Properties seem to be ignored**
267- - Make sure you are modifying the correct `application.yaml` for the active Spring profile
268- - Verify that all configuration keys are indented correctly under the `otel:` root
269- - Double-check that any placeholders use `:` for defaults (e.g., `${OTEL_EXPORTER_OTLP_ENDPOINT:http://localhost:4318}`)
295+ - Make sure you are modifying the correct `application.yaml` for the active Spring profile
296+ - Verify that all configuration keys are indented correctly under the `otel:` root
297+ - Double-check that any placeholders use `:` for defaults (e.g.,
298+ ` ${OTEL_EXPORTER_OTLP_ENDPOINT:http://localhost:4318}` )
270299
271300If issues persist, compare your configuration to :
272301
273302- This module’s [`application.yaml`](./src/main/resources/application.yaml)
274- - The Java Agent example in [`javaagent-declarative-configuration`](../javaagent-declarative-configuration)
303+ - The Java Agent example in [
304+ ` javaagent-declarative-configuration` ](../javaagent-declarative-configuration)
275305- The reference schemas and examples in
276306 [opentelemetry-configuration](https://github.com/open-telemetry/opentelemetry-configuration)
0 commit comments