如何将 TraceId 和 SpanId 注入日志
本文介绍如何将 TraceId 和 SpanId 自动写入日志。TraceId与SpanId写入日志后,可以将分布式链路数据与日志数据关联起来,实现更高效的故障诊断和性能分析。
Java
支持的日志库
- 更多信息,请参考 Logger MDC auto-instrumentation。
日志框架 | 自动埋点支持的版本 | 手动埋点需要引入的依赖 |
---|---|---|
Log4j 1 | 1.2+ | 无 |
Log4j 2 | 2.7+ | opentelemetry-log4j-context-data-2.17-autoconfigure |
Logback | 1.0+ | opentelemetry-logback-mdc-1.0 |
使用 Log4j2
- 在 pom.xml 中添加 OpenTelemetry Log4j2 依赖。
- 请将
${OPENTELEMETRY_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>
- 修改 log4j2.xml 配置,在 pattern 中添加
%X{trace_id}
与%X{span_id}
,可以将 TraceId 与 SpanId 自动写入日志。
- 以下为日志格式示例:
<?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>
使用 Logback
- 在 pom.xml 中添加 OpenTelemetry Logback 依赖。
- 请将
${OPENTELEMETRY_VERSION}
替换为最新版本。
<dependencies> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-logback-mdc-1.0</artifactId> <version>${OPENTELEMETRY_VERSION}</version> </dependency></dependencies>
- 修改 logback.xml 配置,在 pattern 中添加
%X{trace_id}
与%X{span_id}
,可以将 TraceId 与 SpanId 自动写入日志。
- 以下为日志格式示例:
<?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>
**使用 **Logback(SpringBoot 项目)
Spring Boot 项目内置了日志框架,并且默认使用 Logback 作为其日志实现。如果您的 Java 项目为 SpringBoot 项目,只需少量配置即可将 TraceId 写入日志。
- 在 application.properties 中设置 logging.pattern.level,添加
%mdc{trace_id}
与%mdc{span_id}
到日志中:
logging.pattern.level=trace_id=%mdc{trace_id} span_id=%mdc{span_id} %5p
- 以下为日志示例:
2024-06-26 10:56:31.200 trace_id=8f7ebd8a72f9a8f50e6a00a87a20952b 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=8f7ebd8a72f9a8f50e6a00a87a20952b 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=8f7ebd8a72f9a8f50e6a00a87a20952b span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms2024-06-26 10:56:31.296 trace_id=8f7ebd8a72f9a8f50e6a00a87a20952b span_id=5743699405074f4e INFO 53724 --- [nio-8081-exec-1] com.example.httpserver.ot.OTServer : hello world
Go
OpenTelemetry Go 不支持自动注入,需要在记录日志时手动注入 TraceId 和 SpanId。
**使用 **logrus
- 引入依赖。
import ( oteltrace "go.opentelemetry.io/otel/trace" "github.com/sirupsen/logrus")
- 创建工具函数,从 Span 中提取 SpanID 和 TraceID,并添加到 Logrus 日志字段。
func LogrusFields(span oteltrace.Span) logrus.Fields { return logrus.Fields{ "trace_id": span.SpanContext().TraceID().String(), "span_id": span.SpanContext().SpanID().String(), }}
- 在创建一个 Span 后,即可记录带有 TraceId 和 SpanId 的日志。
..._, 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 Python 支持自动将 TraceId 与 SpanId 注入到日志中,更多信息请参考 OpenTelemetry Logging Instrumentation。
使用 logging
- 设置环境变量 OTEL_PYTHON_LOG_CORRELATION 为 true:
export OTEL_PYTHON_LOG_CORRELATION=true
- 在日志格式中添加
%(otelTraceID)s
和%(otelSpanID)s
,OpenTelemetry 会自动将日志中的%(otelTraceID)s
和%(otelSpanID)s
替换为 TraceId 和 SpanId。
- 以下为 logging.Formatter 示例:
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')
- 以下为日志示例:
2024-06-25 10:00:55,494 INFO [app] [app.py:80] [trace_id=70561de6a164ab991bfff2281b7fc9c2 span_id=4b7f3c7984600ea5 resource.service.name=ot-python-demo] - hello world