A new version of Spring Boot has landed, and once again there are quite a bit of improvements to the insights we can gather, and some changes to keep in mind as well.
A new version of Spring Boot has landed, and once again there are quite a bit of improvements to the insights we can gather, and some changes to keep in mind as well.
So I thought: why not take a gander at the new possibilities?
There are a lot of general enhancements, some useful ones for testing, and also ones for Micrometer and OpenTelemetry which further increases our tracing options.
In case you’re not familiar with OpenTelemetry/Micrometer these APIs easily allow us metrics for our application such as meters, rate aggregations, counters, …
While debugging can be quite useful when you’re troubleshooting an issue and have an idea of roughly where the issue is. Setting up proper tracing offers a lot of benefits. (it’s certainly not an A or B situation, but an and!)
If setup correctly we can easily trace the flow of our application logic, and identify potential slowdowns introduced due to our changes or possible bottlenecks.
This becomes even more important as our application complexity increases (although luckily the upcoming structured concurrency & the recently released Virtual Threading will make our life quite a bit easier).
Our tracing can just do its thing in the background (gathering and aggregating the data) whilst we run (and now test, more on that later) our application, unlike debugging which interrupts our application (and generally my workflow).
Now I’m fully cognizant of the fact that there are certain extra steps one has to take for tracing, but luckily the increasing support for Micrometer and OpenTelemetry is making our life easier.
Especially if one combines this with tools such as Digma which smoothly integrates with JetBrains so we don’t even need to leave our development environment to look into these insights, and can automatically provide certain insights such as N+1 issues when querying data.
For example, thanks to this setup I am automatically notified when I introduce an N+1.
The traces are also easily viewable by selecting the function I want to investigate (there’s also a clear overview)
Changes in observability in Spring Boot 3.2 to keep in mind
Testing observability in Spring Boot 3.2
Ideally, you always want to garner your insights as soon as possible, preferably even before your changes have been pushed to your remote repository. As of this release, only the minimal Micrometer Tracing, Brave and OpenTelemetry infrastructure is so that no spans are sent to the backend.
Now if you want to run your integration tests with observability enabled, you merely need to apply `@AutoConfigureObservability` to your test class(es).
Thus allowing us to gather more insights.
Important: verify that if you have custom `SpanExporter` beans that they’re annotated with `@ConditionalOnEnabledTracing`, otherwise they will be created when running integration tests with observability switched off.
Micrometer
We can now use the following annotations: `@Timed, @Counted, @NewSpan, @ContinueSpan and @Observed` and they will be auto-configured if we have AspectJ on the classpath.
@GetMapping("/fetchArticles") @Timed(value = "articles.all", longTask = true) public List<Article> listArticles() { // … }
And `@Scheduled` methods are now instrumented for observability:
@Scheduled(fixedDelay = 60_000) @Timed("execute.synchronization") public void executeSynchronization() { // … }
A couple of important things to keep in mind
The registration of `ObservationHandler` beans has been flipped around. Categorized handlers are now registered before uncategorized ones. (they are still automatically registered)
The broadened exemplar support requires Prometheus 2.43 or later, so don’t forget to upgrade it or you will no longer see your metrics.
OpenTelemetry
The auto-configuration has been further improved in this release:
- SdkLoggerProvider/SdkMeterProvider are not automatically registered on the OTEL bean
- MeterProvider is automatically registered on the BatchSpanProcessor.
The OTel resource is now exposed as a bean, and you can use the new property `management.opentelemetry.resource-attributes` to configure the resource attributes.
You can now further control the applied `SpanProcessor` & `SpanExporter` by defining a bean of type `SpanProcessors` or `SpanExporters` respectively which are all applied by default.
Other relevant changes in observability for spring boot 3.2
Application name in our logs
Our applications logs now automatically contain our application name if `spring.application.name` has been configured.
OTLP configuration
If you rely on `OtlpHttpSpanExporter` and its autoconfiguration, do not forget to set `management.otlp.tracing.endpoint` as it no longer has a default value. (you can set it back to management.otlp.tracing.endpoint=http://localhost:4318/v1/traces )
Logging correlation
We’ve all likely crawled through plenty of log files, and as our applications become bigger, and more complex it’s a task that certainly doesn’t become easier, especially in a microservice-driven architecture.
To follow a (user-driven) request flow through our stack we need some kind of ID => correlation ID which will now be automatically logged when we’re using Micrometer tracing. This ID is based upon the `traceId` and `spanId` mapped diagnostic context.
We can always alter this behaviour:
- disable it by setting `management.tracing.enabled` to false
- no longer include the application name by setting `logging.include-application-name` to false
- define a different logging format using `logging.pattern.correlation`
B3 propagation
The default format for B3 trace propagation has been changed from single-no-parent to single.
R2DBC Observability
If you make use of reactive relational database connectivity, then you can now make use of the newly added observability support by enabling it by adding the io.r2dbc:r2dbc-proxy dependency to your project.
<dependency> <groupId>io.r2dbc</groupId> <artifactId>r2dbc-proxy</artifactId> <version>1.1.3.RELEASE</version> </dependency>
Properties
Context propagation
You can now further manage context propagation in your reactive pipelines. This can be done by configuring `spring.reactor.context-propagation`. In case you want to automatically propagate observations, trace ids and span ids in your reactive pipelines, set the property to auto.
Managing observations
You might not be interested in certain observation groups, this can now be managed on prefix level using properties. Say you’re not interested in observations from Spring Security you can set `management.observations.enable.spring.security` to false.
Applying low-cardinality key-values for all observations
In case you want to apply a key to all observations you can now make use of `management.observations.key-values.*`.
For example, say I want to add that my application region is EU-West to all my logs I can add:
management.observations.key-values.region=eu-west-1
My thoughts:
Observability was a real focus point in Spring Boot 3.0, and it’s magnificent to see this trend continuing.
The complexity of our applications is ever-increasing, and with virtual threading and structured concurrency looming ahead the necessity of proper tracing is becoming increasingly important (good luck with some race conditions for example).
The new paradigms that are still very much developing will require proper insights, since while the blocking factor might no longer be CPU-bound threads, this might lead to new blockers elsewhere.
One of the reasons I’m glad for these enhancements is that I’ve been using Digma for quite a while now, to monitor the impact of my changes, and potential issues within my IDE. Digma is a tool which integrates with OTEL, that I can use from within my IDE and supports Java & Kotlin.
So please take a look at OpenTelemetry, micrometer and Digma to stay up to date on what’s going on in your application! If you take the time to build this in properly, it will save you so many headaches, compared to a mysterious blocking ticket on a Friday afternoon!
Some useful resources:
- Spring Boot: observability documentation
- Micrometer: reference documentation
- OpenTelemetry: documentation on how observability works
- Digma: the referenced tool
- Digma: guide to setting it up for your application
- Couch to Fully-Observed Code with Spring Boot 3.2, Micrometer Tracing, and Digma
- Digma blog: why swift feedback matters
Getting in Touch
I’m always happy to receive feedback/questions or just generally an interesting conversation.
In case you want to reach out I can be found at: