美文网首页
Sleuth输出TraceId

Sleuth输出TraceId

作者: huiwq1990 | 来源:发表于2019-11-25 20:48 被阅读0次

    一、环境搭建

    1.1包配置

        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-sleuth</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zipkin</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    

    1.2日志配置

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scanPeriod="60 seconds" debug="false">
        <!-- https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html -->
    
        <property name="CONSOLE_LOG_PATTERN"
                  value="[%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %X{X-B3-TraceId} %X{traceId} %yellow(%X{X-B3-TraceId}),%green(%X{X-B3-SpanId}),%blue(%X{X-B3-ParentSpanId}) %yellow(%thread) %green(%logger) %msg%n"/>
    
        <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    
        <!--<include resource="org/springframework/boot/logging/logback/base.xml"/>-->
        <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
        
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    
    </configuration>
    

    二、实现分析

    2.1 sleuth日志插件

    org.springframework.cloud.sleuth.log.Slf4jCurrentTraceContext#newScope

    1. 获取父span设置的信息
      2)将当前span的信息设置到MDC中,如果当前span为空,需要从MDC中移除。
      3)当span close时,将MDC设置为父级span信息。
    @Override public Scope newScope(@Nullable TraceContext currentSpan) {
            final String previousTraceId = MDC.get("traceId");
            final String previousParentId = MDC.get("parentId");
            final String previousSpanId = MDC.get("spanId");
            final String spanExportable = MDC.get("spanExportable");
            final String legacyPreviousTraceId = MDC.get(LEGACY_TRACE_ID_NAME);
            final String legacyPreviousParentId = MDC.get(LEGACY_PARENT_ID_NAME);
            final String legacyPreviousSpanId = MDC.get(LEGACY_SPAN_ID_NAME);
            final String legacySpanExportable = MDC.get(LEGACY_EXPORTABLE_NAME);
    
            if (currentSpan != null) {
                String traceIdString = currentSpan.traceIdString();
                MDC.put("traceId", traceIdString);
                MDC.put(LEGACY_TRACE_ID_NAME, traceIdString);
                String parentId = currentSpan.parentId() != null ?
                        HexCodec.toLowerHex(currentSpan.parentId()) :
                        null;
                replace("parentId", parentId);
                replace(LEGACY_PARENT_ID_NAME, parentId);
                String spanId = HexCodec.toLowerHex(currentSpan.spanId());
                MDC.put("spanId", spanId);
                MDC.put(LEGACY_SPAN_ID_NAME, spanId);
    

    2.2 Logback获取MDC信息

    Logback对象层级关系:Logger -> Appender -> Encoder -> PatternLayout,Layout中head定义了pattern的convert。

    ch.qos.logback.core.OutputStreamAppender#subAppend

    subAppend调用prepareForDeferredProcessing设置MDC。

        public void prepareForDeferredProcessing() {
            this.getFormattedMessage();
            this.getThreadName();
            // fixes http://jira.qos.ch/browse/LBCLASSIC-104
            this.getMDCPropertyMap();
        }
    

    2.3 MDCConvert

    %X{X-B3-TraceId}被定义为MDCConverter,它从MDC中获取信息。

     @Override
        public String convert(ILoggingEvent event) {
            Map<String, String> mdcPropertyMap = event.getMDCPropertyMap();
    
            if (mdcPropertyMap == null) {
                return defaultValue;
            }
    
            if (key == null) {
                return outputMDCForAllKeys(mdcPropertyMap);
            } else {
    
                String value = mdcPropertyMap.get(key);
                if (value != null) {
                    return value;
                } else {
                    return defaultValue;
                }
            }
        }
    
    image.png

    相关文章

      网友评论

          本文标题:Sleuth输出TraceId

          本文链接:https://www.haomeiwen.com/subject/jbzjwctx.html