This topic describes how to use OpenTelemetry to automatically write trace IDs and span IDs to logs. After trace IDs and span IDs are written to logs, you can associate distributed trace data with log data for more efficient fault diagnostics and performance analysis.
Java
Supported logging libraries
For more information, see Logger MDC auto-instrumentation.
Logging framework | Version that supports automatic instrumentation | Required dependency to be introduced for manual instrumentation |
Log4j1 | 1.2 and later | N/A |
Log4j2 | 2.7 and later | |
Logback | 1.0 and later |
Use Log4j2
Add the OpenTelemetry Log4j2 dependency to the pom.xml file.
Replace
OPENTELEMETRY_VERSION
with the latest version.<dependencies> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-log4j-context-data-2.17-autoconfigure</artifactId> <version>OPENTELEMETRY_VERSION</version> <scope>runtime</scope> </dependency> </dependencies>
Open log4j2.xml, and add
%X{trace_id}
and%X{span_id}
to pattern to enable automatic writing of trace IDs and span IDs to logs.The following example shows the log format:
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} - %msg%n"/> </Console> </Appenders> <Loggers> <Root> <AppenderRef ref="Console" level="All"/> </Root> </Loggers> </Configuration>
Use Logback
Add the OpenTelemetry Logback dependency to the pom.xml file.
Replace
OPENTELEMETRY_VERSION
with the latest version.<dependencies> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-logback-mdc-1.0</artifactId> <version>OPENTELEMETRY_VERSION</version> </dependency> </dependencies>
Open logback.xml, and add
%X{trace_id}
and%X{span_id}
to pattern to enable automatic writing of trace IDs and span IDs to logs.The following example shows the log format:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} %msg%n</pattern> </encoder> </appender> <!-- Just wrap your logging appender, for example ConsoleAppender, with OpenTelemetryAppender --> <appender name="OTEL" class="io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender"> <appender-ref ref="CONSOLE"/> </appender> <!-- Use the wrapped "OTEL" appender instead of the original "CONSOLE" one --> <root level="INFO"> <appender-ref ref="OTEL"/> </root> </configuration>
Use Logback (Spring Boot projects)
A Spring Boot project has a built-in logging framework, which is Logback by default. If you are developing a Java Spring Boot project, you can enable automatic writing of trace IDs and span IDs to logs with simple configuration.
Open the application.properties file and add application.properties
and %mdc{span_id}
to logging.pattern.level.
logging.pattern.level=trace_id=%mdc{trace_id} span_id=%mdc{span_id} %5p
The following example shows some logs:
2024-06-26 10:56:31.200 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-06-26 10:56:31.201 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-06-26 10:56:31.209 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms
2024-06-26 10:56:31.296 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=5743699405074f4e INFO 53724 --- [nio-8081-exec-1] com.example.httpserver.ot.OTServer : hello world
Go
OpenTelemetry in Go does not support automatic writing of trace IDs and span IDs to logs. If you do not perform extra development operations such as the following ones, you need to manually record trace IDs and span IDs.
Use logrus
Add dependencies.
import ( oteltrace "go.opentelemetry.io/otel/trace" "github.com/sirupsen/logrus" )
Create a tool function to extract trace IDs and span IDs from spans and add them to the Logrus log field.
func LogrusFields(span oteltrace.Span) logrus.Fields { return logrus.Fields{ "trace_id": span.SpanContext().TraceID().String(), "span_id": span.SpanContext().SpanID().String(), } }
After a span is created, a log with a trace ID and a span ID is generated.
... _, span := tracer.Start(ctx, "spanName") defer span.End() logEntry := logrus.WithFields(LogrusFields(span)) logEntry.Info("This is an info message with trace and span ID") ...
Python
OpenTelemetry in Python supports automatic writing of trace IDs and span IDs to logs. For more information, see OpenTelemetry Logging Instrumentation.
Use logging
Set the OTEL_PYTHON_LOG_CORRELATION environment variable to
true
to enable automatic writing of trace IDs and span IDs to logs.export OTEL_PYTHON_LOG_CORRELATION=true
Add
%(otelTraceID)s
and%(otelSpanID)s
to the log format. OpenTelemetry automatically replaces%(otelTraceID)s
and%(otelSpanID)s
in logs with trace IDs and span IDs.The following example shows a log format:
formatter = logging.Formatter( '%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s] - %(message)s' )
The following example shows a log:
2024-06-25 10:00:55,494 INFO [app] [app.py:80] [trace_id=70561de6a164ac991bfff2281b7f**** span_id=4b7f3c798460**** resource.service.name=ot-python-demo] - hello world
Operation example
In the following example, a demo application named Helloword is used to show how to automatically write trace IDs and span IDs to logs in Python.
Before you start, make sure that Python and pip are installed. In this example, Python 3.12.4 and pip 24.1.1 are used.
Install the Flask framework.
pip3 install flask
Expected output:
Successfully installed Jinja2-3.1.4 MarkupSafe-2.1.5 Werkzeug-3.0.3 blinker-1.8.2 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0
If information similar to the preceding output is displayed, the installation is successful.
Install the required OpenTelemetry Python packages and tools.
pip3 install opentelemetry-distro \ opentelemetry-exporter-otlp opentelemetry-bootstrap -a install
Expected output:
Successfully installed opentelemetry-instrumentation-dbapi-0.46b0 Successfully installed opentelemetry-instrumentation-requests-0.46b0 Successfully installed opentelemetry-instrumentation-urllib3-0.46b0
If information similar to the preceding output is displayed, the installation is successful.
Create an application by using the sample code.
import logging from logging.handlers import RotatingFileHandler from flask import Flask import os app = Flask(__name__) # Create a formatter that contains the OpenTelemetry context. formatter = logging.Formatter( '%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s] - %(message)s' ) # Create a RotatingFileHandler to write logs to a file. # Replace /path/to/app.log with the actual path of the log file. file_handler = RotatingFileHandler('/path/to/app.log', maxBytes=10000, backupCount=1) file_handler.setLevel(logging.INFO) file_handler.setFormatter(formatter) app.logger.addHandler(file_handler) @app.route('/') def hello_world(): app.logger.info('Hello World!!!') return 'Hello, World!' if __name__ == '__main__': app.run()
Run the demo application. Expected output:
* Running on http://127.0.**.**:5000
If information similar to the preceding output is displayed, the application deployment is successful.
Set environment variables to enable automatic writing of trace IDs and span IDs to logs and use OpenTelemetry to automatically instrument the demo application.
export OTEL_PYTHON_LOG_CORRELATION=true export OTEL_SERVICE_NAME=ot-python-demo export OTEL_TRACES_EXPORTER=otlp export OTEL_METRICS_EXPORTER=none # Replace test.py with the actual file name. opentelemetry-instrument python3 test.py
View the log file. The following example shows a log:
2024-06-25 10:00:55,494 INFO [app] [test.py:80] [trace_id=70561de6a164ac991bfff2281b7f**** span_id=4b7f3c798460**** resource.service.name=ot-python-demo] - hello world
In this example, a trace ID and a span ID are recorded in the log.