[[actuator.micrometer-tracing]]
== Tracing
Spring Boot Actuator provides dependency management and auto-configuration for https://micrometer.io/docs/tracing[Micrometer Tracing], a facade for popular tracer libraries.

TIP: To learn more about Micrometer Tracing capabilities, see its https://micrometer.io/docs/tracing[reference documentation].



[[actuator.micrometer-tracing.tracers]]
=== Supported Tracers
Spring Boot ships auto-configuration for the following tracers:

* https://opentelemetry.io/[OpenTelemetry] with https://zipkin.io/[Zipkin] or https://docs.wavefront.com/[Wavefront]
* https://github.com/openzipkin/brave[OpenZipkin Brave] with https://zipkin.io/[Zipkin] or https://docs.wavefront.com/[Wavefront]



[[actuator.micrometer-tracing.getting-started]]
=== Getting Started
We need an example application that we can use to get started with tracing.
For our purposes, the simple "`Hello World!`" web application that's covered in the "`<<getting-started#getting-started.first-application>>`" section will suffice.
We're going to use the OpenTelemetry tracer with Zipkin as trace backend.

To recap, our main application code looks like this:

include::code:MyApplication[]

NOTE: There's an added logger statement in the `home()` method, which will be important later.

Now we have to add the following dependencies:

* `org.springframework.boot:spring-boot-starter-actuator`
* `io.micrometer:micrometer-tracing-bridge-otel` - which is needed to bridge the Micrometer Observation API to OpenTelemetry.
* `io.opentelemetry:opentelemetry-exporter-zipkin` - which is needed to report https://micrometer.io/docs/tracing#_glossary[traces] to Zipkin.

Add the following application properties:

[source,yaml,indent=0,subs="verbatim",configprops,configblocks]
----
	management:
	  tracing:
	    sampling:
	      probability: 1.0
----

By default, Spring Boot samples only 10% of requests to prevent overwhelming the trace backend.
This property switches it to 100% so that every request is sent to the trace backend.

To collect and visualize the traces, we need a running trace backend.
We use Zipkin as our trace backend here.
The https://zipkin.io/pages/quickstart[Zipkin Quickstart guide] provides instructions how to start Zipkin locally.

After Zipkin is running, you can start your application.

If you open a web browser to `http://localhost:8080`, you should see the following output:

[indent=0]
----
	Hello World!
----

Behind the scenes, an observation has been created for the HTTP request, which in turn gets bridged to OpenTelemetry, which reports a new trace to Zipkin.

Now open the Zipkin UI at `http://localhost:9411` and press the "Run Query" button to list all collected traces.
You should see one trace.
Press the "Show" button to see the details of that trace.

TIP: You can include the current trace and span id in the logs by setting the configprop:logging.pattern.level[] property to `%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]`



[[actuator.micrometer-tracing.propagating-traces]]
=== Propagating Traces
To automatically propagate traces over the network, use the auto-configured <<io#io.rest-client.resttemplate, `RestTemplateBuilder`>> or <<io#io.rest-client.webclient, `WebClient.Builder`>> to construct the client.

WARNING: If you create the `WebClient` or the `RestTemplate` without using the auto-configured builders, automatic trace propagation won't work!



[[actuator.micrometer-tracing.tracer-implementations]]
=== Tracer Implementations
As Micrometer Tracer supports multiple tracer implementations, there are multiple dependency combinations possible with Spring Boot.

All tracer implementations need the `org.springframework.boot:spring-boot-starter-actuator` dependency.



[[actuator.micrometer-tracing.tracer-implementations.otel-zipkin]]
==== OpenTelemetry With Zipkin
Tracing with OpenTelemetry and reporting to Zipkin requires the following dependencies:

* `io.micrometer:micrometer-tracing-bridge-otel` - bridges the Micrometer Observation API to OpenTelemetry.
* `io.opentelemetry:opentelemetry-exporter-zipkin` - reports traces to Zipkin.

Use the `management.zipkin.tracing.*` configuration properties to configure reporting to Zipkin.



[[actuator.micrometer-tracing.tracer-implementations.otel-wavefront]]
==== OpenTelemetry With Wavefront
Tracing with OpenTelemetry and reporting to Wavefront requires the following dependencies:

* `io.micrometer:micrometer-tracing-bridge-otel` - bridges the Micrometer Observation API to OpenTelemetry.
* `io.micrometer:micrometer-tracing-reporter-wavefront` - reports traces to Wavefront.

Use the `management.wavefront.*` configuration properties to configure reporting to Wavefront.



[[actuator.micrometer-tracing.tracer-implementations.brave-zipkin]]
==== OpenZipkin Brave With Zipkin
Tracing with OpenZipkin Brave and reporting to Zipkin requires the following dependencies:

* `io.micrometer:micrometer-tracing-bridge-brave` - bridges the Micrometer Observation API to Brave.
* `io.zipkin.reporter2:zipkin-reporter-brave` - reports traces to Zipkin.

NOTE: If your project doesn't use Spring MVC or Spring WebFlux, the `io.zipkin.reporter2:zipkin-sender-urlconnection` dependency is needed, too.

Use the `management.zipkin.tracing.*` configuration properties to configure reporting to Zipkin.



[[actuator.micrometer-tracing.tracer-implementations.brave-wavefront]]
==== OpenZipkin Brave With Wavefront
Tracing with OpenZipkin Brave and reporting to Wavefront requires the following dependencies:

* `io.micrometer:micrometer-tracing-bridge-brave` - which is needed to bridge the Micrometer Observation API to Brave.
* `io.micrometer:micrometer-tracing-reporter-wavefront` - which is needed to report traces to Wavefront.

Use the `management.wavefront.*` configuration properties to configure reporting to Wavefront.



[[actuator.micrometer-tracing.micrometer-observation]]
=== Integration with Micrometer Observation

A `TracingAwareMeterObservationHandler` is automatically registered on the `ObservationRegistry`, which creates spans for every completed observation.

[[actuator.micrometer-tracing.creating-spans]]
=== Creating Custom Spans
You can create your own spans by starting an observation.
For this, inject `ObservationRegistry` into your component:

include::code:CustomObservation[]

This will create an observation named "some-operation" with the tag "some-tag=some-value".

TIP: If you want to create a span without creating a metric, you need to use the https://micrometer.io/docs/tracing#_using_micrometer_tracing_directly[lower-level `Tracer` API] from Micrometer.



[[actuator.micrometer-tracing.baggage]]
=== Baggage
You can create baggage with the `Tracer` API:

include::code:CreatingBaggage[]

This example creates baggage named `baggage1` with the value `value1`.
The baggage is automatically propagated over the network if you're using W3C propagation.
If you're using B3 propagation, baggage is not automatically propagated.
To manually propagate baggage over the network, use the configprop:management.tracing.baggage.remote-fields[] configuration property (this works for W3C, too).
For the example above, setting this property to `baggage1` results in an HTTP header `baggage1: value1`.

If you want to propagate the baggage to the MDC, use the configprop:management.tracing.baggage.correlation.fields[] configuration property.
For the example above, setting this property to `baggage1` results in an MDC entry named `baggage1`.
