OpenTelemetry

OpenTelemetry 是一个开源项目,旨在通过统一的工具集、API和SDK,简化在多样化的技术栈中集成可观测性功能,确保一致地收集、处理及导出应用性能数据。

如何将 TraceId 和 SpanId 注入日志


本文介绍如何将 TraceId 和 SpanId 自动写入日志。TraceId与SpanId写入日志后,可以将分布式链路数据与日志数据关联起来,实现更高效的故障诊断和性能分析。

Java

支持的日志库

日志框架自动埋点支持的版本手动埋点需要引入的依赖
Log4j 11.2+
Log4j 22.7+opentelemetry-log4j-context-data-2.17-autoconfigure
Logback1.0+opentelemetry-logback-mdc-1.0

使用 Log4j2

  1. 在 pom.xml 中添加 OpenTelemetry Log4j2 依赖。
<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>
  1. 修改 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

  1. 在 pom.xml 中添加 OpenTelemetry Logback 依赖。
<dependencies>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-logback-mdc-1.0</artifactId>
<version>${OPENTELEMETRY_VERSION}</version>
</dependency>
</dependencies>
  1. 修改 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 ms
2024-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

  1. 引入依赖。
import (
oteltrace "go.opentelemetry.io/otel/trace"
"github.com/sirupsen/logrus"
)
  1. 创建工具函数,从 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(),
}
}
  1. 在创建一个 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

  1. 设置环境变量 OTEL_PYTHON_LOG_CORRELATION 为 true:
export OTEL_PYTHON_LOG_CORRELATION=true
  1. 在日志格式中添加%(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

observability.cn Authors 2024 | Documentation Distributed under CC-BY-4.0
Copyright © 2017-2024, Alibaba. All rights reserved. Alibaba has registered trademarks and uses trademarks.
浙ICP备2021005855号-32