What is Micrometer Tracing, and what does a 'tracing bridge' (bridge-otel / bridge-brave) actually do?
answer
- facade + one bridge JAR = tracer choice
- bridge-otel = OpenTelemetry, bridge-brave = Brave/Zipkin
- replaced Spring Cloud Sleuth in Boot 3
- bridge != exporter
- code imports only Micrometer types
basics
~20 sMicrometer Tracing is a vendor-neutral facade for distributed tracing. A bridge plugs a real tracer (OpenTelemetry or Brave/Zipkin) behind that facade, so your code uses one API while the bridge does the actual span work.
solid answer
~40 sMicrometer Tracing is the tracing facade that replaced Spring Cloud Sleuth in Spring Boot 3. Your code depends only on its neutral API — the Tracer, Span, and SpanInScope abstractions. It does no tracing itself; it delegates to a concrete tracer chosen by which bridge JAR is on the classpath. Add micrometer-tracing-bridge-otel and you get OpenTelemetry as the SDK; add micrometer-tracing-bridge-brave and you get Brave (the OpenZipkin library). You pick exactly one bridge. The bridge translates Micrometer's Span/TraceContext calls into that library's objects, and a separate exporter dependency ships the finished spans to a backend such as Zipkin or an OTLP collector. This lets you swap tracer implementations without touching application code.
code
java · 23 lines// build.gradle — facade + ONE bridge + ONE exporter
// implementation 'org.springframework.boot:spring-boot-starter-actuator'
// implementation 'io.micrometer:micrometer-tracing-bridge-otel' // choose OTel...
// implementation 'io.opentelemetry:opentelemetry-exporter-otlp' // ...and OTLP export
// Application code depends ONLY on the Micrometer facade:
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.Span;
@Service
class PricingService {
private final Tracer tracer; // injected; impl comes from the bridge
PricingService(Tracer tracer) { this.tracer = tracer; }
void price() {
Span span = tracer.nextSpan().name("price");
try (Tracer.SpanInScope scope = tracer.withSpan(span.start())) {
span.tag("tier", "gold");
} finally {
span.end();
}
}
}go deeper
Know it's a facade + a bridge picks the real tracer (OTel or Brave); replaced Sleuth.
Distinguish bridge from exporter; know the two bridge artifacts and matching exporters.
Explain Observation→span integration and that only sampled spans export while ids always propagate.
Reason about migration from Sleuth/Brave to OTel, standardization on OTLP, and ecosystem trade-offs.
## The problem it solves **Distributed tracing** records the path of one request as it hops across services. Each unit of work is a **span** (an operation with a start time, duration, name, tags, and events); spans sharing a **trace id** form one **trace**. To make this work you need a library that creates spans, propagates ids across network calls, samples, and exports to a backend. Historically Spring used **Spring Cloud Sleuth**, which was tightly coupled to Brave. In **Spring Boot 3+** that was replaced by **Micrometer Tracing**. ## What Micrometer Tracing is Micrometer Tracing is a **facade** — a thin, vendor-neutral API. Its key abstractions: - `io.micrometer.tracing.Tracer` — creates/starts spans and exposes the current span. - `io.micrometer.tracing.Span` — one operation; you `tag(...)`, add `event(...)`, and `end()` it. - `Tracer.SpanInScope` — an `AutoCloseable` that marks a span as *current* on the thread. - `TraceContext` / `Baggage` — the propagated ids and custom key/value context. Critically, the facade contains **no tracing logic**. It needs a concrete implementation supplied at runtime. ## What a bridge does A **bridge** is the adapter that connects the Micrometer facade to a real tracer library. There are two official bridges, and you add **exactly one**: - `io.micrometer:micrometer-tracing-bridge-otel` → backs the facade with the **OpenTelemetry** SDK. Micrometer `Span` calls become OpenTelemetry `io.opentelemetry.api.trace.Span` calls. - `io.micrometer:micrometer-tracing-bridge-brave` → backs the facade with **Brave** (the OpenZipkin tracer). Micrometer calls become `brave.Span` calls. The bridge is *the choice of tracer implementation*. Your application code never imports OpenTelemetry or Brave types — only Micrometer's — so switching bridges is a dependency change, not a code change. ## The bridge is not the exporter Creating spans and **exporting** them are separate concerns. The bridge produces spans in the chosen library's format; a separate **exporter/reporter** dependency ships them: - Brave bridge → `io.zipkin.reporter2:zipkin-reporter-brave` sends to **Zipkin**. - OTel bridge → `io.opentelemetry:opentelemetry-exporter-zipkin` (to Zipkin) or `opentelemetry-exporter-otlp` (to an **OTLP** collector). Spring Boot auto-configures the exporter when its endpoint property (`management.zipkin.tracing.endpoint` or `management.otlp.tracing.endpoint`) is present. ## Auto-configuration in Spring Boot With `spring-boot-starter-actuator` plus a bridge plus an exporter, Boot's `TracingAutoConfiguration` and bridge-specific auto-config wire a `Tracer`, propagators, and the exporter. Tracing also integrates with **Micrometer Observation**: every `Observation` (HTTP server/client, `@Observed`, scheduled tasks) automatically opens and closes a span via `DefaultTracingObservationHandler`, so you often get traces without writing span code at all. ## When to use which - **OTel bridge** is the modern default: OpenTelemetry is the CNCF standard, supports OTLP natively, and has the broadest ecosystem. - **Brave bridge** suits shops already standardized on Zipkin/Brave or needing a specific Brave feature. ## Gotchas - Adding **both** bridges is a misconfiguration — pick one. - A bridge with **no exporter** still creates spans and propagates context but sends nothing to a backend. - Only **sampled** spans are exported; ids are still propagated for unsampled traces.
- What replaced Spring Cloud Sleuth, and why the change?Micrometer Tracing replaced Sleuth in Spring Boot 3. Sleuth was Brave-coupled and tied to the Spring Cloud release train; Micrometer Tracing is a neutral facade with swappable bridges (OTel or Brave), aligning tracing with the Micrometer Observation API.
- If you add a bridge but no exporter dependency, what happens?Spans are still created and trace context is still propagated across calls (and shows up in MDC/logs), but nothing is shipped to a backend like Zipkin — you get correlation ids in logs but no trace UI.
saying these in an interview costs you the question
- Thinking Micrometer Tracing itself creates/exports spans without a bridge
- Adding both bridge-otel and bridge-brave at once
- Believing the bridge also exports (confusing bridge with the exporter dependency)
- Claiming Spring Cloud Sleuth is still the Boot 3 tracing library