
# 使用OpenTelemetry将TraceID和SpanID自动写入日志
TraceID和SpanID写入日志后，可以将链路追踪与日志数据关联起来，实现高效的性能分析以及故障诊断。本章节介绍如何使用OpenTelemetry将TraceID和SpanID自动写入日志。
#### Java
[更多信息](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/logger-mdc-instrumentation.md)
表1日志库信息 
| **日志框架** | **自动埋点支持的版本** | **手动埋点是否需要引入依赖**                                                                                                                                                                   |
|:---|:---|:---|
| Log4j1   | 1.2+          | 否                                                                                                                                                                                  |
| Log4j2   | 2.7+          | [是，详见详细信息。](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure) |
| Logback  | 1.0+          | [是，详见详细信息。](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/logback/logback-mdc-1.0/library)                                        |
   
- **使用Log4j2**
  1. 在pom.xml中添加OpenTelemetry Log4j2依赖，请将OPENTELEMETRY_VERSION替换为[最新版本](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions)。示例如下：
     ```
     <artifactId>opentelemetry-log4j-context-data-2.17-autoconfigure</artifactId>
     ```
     
  
  2. 修改log4j2.xml配置，在pattern中添加%X{trace_id} 与%X{span_id}，可以将TraceID自动写入日志。 日志格式示例如下：
     ```
     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"/>
     ```
     
   
- **使用Logback**
  1. 在pom.xml中添加OpenTelemetry Logback依赖。请将OPENTELEMETRY_VERSION替换为[最新版本](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions)。
     1. 示例如下：
        ```
        <artifactId>opentelemetry-logback-mdc-1.0</artifactId>
        ```
        
     
     2. 修改log4j2.xml配置，在pattern中添加%X{trace_id} 与%X{span_id}，可以将TraceID自动写入日志。 日志格式示例如下：
        ```
        <pattern>%d{HH:mm:ss.SSS} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} %msg%n</pattern>
        ```
        
      
   
- **使用Logback（SpringBoot项目）**
  Spring Boot项目已经内置了日志框架，默认使用Logback实现日志相关功能。因此，只需增加少量配置即可实现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
  ```
  GO
  OpenTelemetry Go需要在记录日志时手动添加TraceID和SpanID。
  1. 引入依赖。
     ```
     import (
          oteltrace "go.opentelemetry.io/otel/trace"    
          "github.com/sirupsen/logrus"
     )
     ```
     
  
  2. 创建工具函数，从Span中提取TraceID和SpanID，并添加到Logrus日志字段。
     ```
     func LogrusFields(span oteltrace.Span) logrus.Fields {
          return logrus.Fields{
              "trace_id": span.SpanContext().TraceID().String(),
              "span_id": span.SpanContext().SpanID().String(),
          }
      }
     ```
     
  
  3. 创建一个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 SpanID")
      ...
     ```
     Python
     OpenTelemetry Python支持自动将TraceID与SpanID写入日志中。如需要获取更多信息，请参见 [OpenTelemetry 日志的简介](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/logging/logging.html)。
     1. 设置环境变量OTEL_PYTHON_LOG_CORRELATION为true，开启自动将TraceID与SpanID添加到日志条目中的能力。
        ```
        export OTEL_PYTHON_LOG_CORRELATION=true
        ```
        
     
     2. 在日志格式中添加%(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'
        )
        ```
        
      
   
 
