Correlating Application Logs with Traces
When the OpenTelemetry Java agent instruments your application, it can automatically add the active trace context — trace_id, span_id, and trace_flags — to your application's logging context (MDC). By printing these values in your log output, you can pivot directly from a log line to its corresponding trace, and from a trace back to the logs that a request produced.
This page explains how to surface the trace context in logs for Java applications.
Prerequisite: this guide assumes your application is already instrumented by the OpenTelemetry Java agent 2.x, injected through the Instrumentation custom resource and the instrumentation.opentelemetry.io/inject-java annotation. The MDC keys described below are populated by the agent at runtime — if the agent is not injected, these keys will be empty no matter how you configure the log pattern. See Java Auto-instrumentation to enable injection first.
TOC
How it worksSurfacing the IDs in your log outputSpring BootLogbackLog4j 2OpenTelemetry agent keys vs. Spring Boot / Micrometer native correlationExporting logs through OTLPOther languagesReferencesHow it works
The Java agent ships logging instrumentations that copy the current span context into your logging library's MDC (Mapped Diagnostic Context). You do not parse HTTP headers or write any code to do this — the agent extracts the context from propagation headers and populates the MDC automatically. The injected keys are:
These keys use snake_case and are the agent's built-in defaults. Injection is enabled by default, so the only thing you have to do is reference the keys in your log output pattern.
The instrumentation is matched to your logging library:
If you ever need to turn a specific injection off (or back on), set the corresponding property or environment variable on the workload. Each defaults to true:
Surfacing the IDs in your log output
Choose the option that matches how your application is configured. All three reference the same snake_case MDC keys, so a sampled request produces a log line such as:
Spring Boot
For a Spring Boot application, the simplest approach is to override logging.pattern.level so the IDs are prepended to every log line without rewriting the whole pattern:
This is the exact form documented in the upstream OpenTelemetry instrumentation README (see References). Overriding logging.pattern.level is a Spring Boot convention; the snake_case keys are what the agent provides.
Logback
If you manage your own logback.xml or logback-spring.xml, reference the keys with %X{...} (which is equivalent to %mdc{...} in Logback) inside the pattern:
For applications that rely on Spring Boot's default console appender, you can override the CONSOLE_LOG_PATTERN property instead, embedding the same %X{trace_id} tokens in the pattern.
Log4j 2
For Log4j 2, reference the keys with %X{...} in a PatternLayout:
OpenTelemetry agent keys vs. Spring Boot / Micrometer native correlation
The snake_case keys (trace_id, span_id, trace_flags) apply when the OpenTelemetry Java agent is the source of the trace context — which is the assumption throughout this documentation.
Spring Boot 3 with Micrometer Tracing has its own, separate log-correlation feature that uses camelCase keys (traceId, spanId) through logging.pattern.correlation. That is a different mechanism from the agent.
Use the keys that match your trace source. If you reference %X{traceId} while the agent (not Micrometer) supplies the context, the field prints empty — and likewise %X{trace_id} is empty when only Micrometer is active. Do not mix the two conventions.
Exporting logs through OTLP
The patterns above are for textual logs (console or file) that are read or scraped as text. If you instead export logs directly through OTLP, the trace_id and span_id are carried in the OTLP log record's dedicated fields rather than as MDC attributes, so OTLP-exported logs stay correlated without adding the IDs to the log pattern.
Other languages
The other OpenTelemetry languages also correlate logs with traces under zero-code (auto-instrumentation), but the injected field names and how you enable them differ per language. Refer to the upstream guidance for the language you use:
Go is intentionally omitted: it has no runtime agent, and its eBPF-based auto-instrumentation does not inject trace context into application logs. Log-trace correlation in Go is done manually in code — for example, by reading the span context from context.Context, or via the otelslog bridge — so there is no zero-code reference to link here.
References
- Logger MDC auto-instrumentation — the authoritative list of injected keys and supported logging libraries.
- Logback MDC instrumentation README — pattern examples and configuration options.
- Java agent configuration and suppressing specific instrumentation — how to toggle individual instrumentations.