• 聊聊TraceIdPatternLogbackLayout


    本文主要研究一下TraceIdPatternLogbackLayout

    TraceIdPatternLogbackLayout

    org/apache/skywalking/apm/toolkit/log/logback/v1/x/TraceIdPatternLogbackLayout.class

    public class TraceIdPatternLogbackLayout extends PatternLayout {
        public TraceIdPatternLogbackLayout() {
        }
    
        static {
            defaultConverterMap.put("tid", LogbackPatternConverter.class.getName());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    skywalking的TraceIdPatternLogbackLayout继承了PatternLayout,其static方法往defaultConverterMap添加了tid,value为LogbackPatternConverter.class.getName()

    PatternLayout

    ch/qos/logback/classic/PatternLayout.java

    public class PatternLayout extends PatternLayoutBase {
    
        public static final Map defaultConverterMap = new HashMap();
        public static final String HEADER_PREFIX = "#logback.classic pattern: ";
    
        static {
            defaultConverterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
    
            defaultConverterMap.put("d", DateConverter.class.getName());
            defaultConverterMap.put("date", DateConverter.class.getName());
    
            defaultConverterMap.put("r", RelativeTimeConverter.class.getName());
            defaultConverterMap.put("relative", RelativeTimeConverter.class.getName());
    
            defaultConverterMap.put("level", LevelConverter.class.getName());
            defaultConverterMap.put("le", LevelConverter.class.getName());
            defaultConverterMap.put("p", LevelConverter.class.getName());
    
            defaultConverterMap.put("t", ThreadConverter.class.getName());
            defaultConverterMap.put("thread", ThreadConverter.class.getName());
    
            defaultConverterMap.put("lo", LoggerConverter.class.getName());
            defaultConverterMap.put("logger", LoggerConverter.class.getName());
            defaultConverterMap.put("c", LoggerConverter.class.getName());
    
            defaultConverterMap.put("m", MessageConverter.class.getName());
            defaultConverterMap.put("msg", MessageConverter.class.getName());
            defaultConverterMap.put("message", MessageConverter.class.getName());
    
            defaultConverterMap.put("C", ClassOfCallerConverter.class.getName());
            defaultConverterMap.put("class", ClassOfCallerConverter.class.getName());
    
            defaultConverterMap.put("M", MethodOfCallerConverter.class.getName());
            defaultConverterMap.put("method", MethodOfCallerConverter.class.getName());
    
            defaultConverterMap.put("L", LineOfCallerConverter.class.getName());
            defaultConverterMap.put("line", LineOfCallerConverter.class.getName());
    
            defaultConverterMap.put("F", FileOfCallerConverter.class.getName());
            defaultConverterMap.put("file", FileOfCallerConverter.class.getName());
    
            defaultConverterMap.put("X", MDCConverter.class.getName());
            defaultConverterMap.put("mdc", MDCConverter.class.getName());
    
            defaultConverterMap.put("ex", ThrowableProxyConverter.class.getName());
            defaultConverterMap.put("exception", ThrowableProxyConverter.class.getName());
            defaultConverterMap.put("rEx", RootCauseFirstThrowableProxyConverter.class.getName());
            defaultConverterMap.put("rootException", RootCauseFirstThrowableProxyConverter.class.getName());
            defaultConverterMap.put("throwable", ThrowableProxyConverter.class.getName());
    
            defaultConverterMap.put("xEx", ExtendedThrowableProxyConverter.class.getName());
            defaultConverterMap.put("xException", ExtendedThrowableProxyConverter.class.getName());
            defaultConverterMap.put("xThrowable", ExtendedThrowableProxyConverter.class.getName());
    
            defaultConverterMap.put("nopex", NopThrowableInformationConverter.class.getName());
            defaultConverterMap.put("nopexception", NopThrowableInformationConverter.class.getName());
    
            defaultConverterMap.put("cn", ContextNameConverter.class.getName());
            defaultConverterMap.put("contextName", ContextNameConverter.class.getName());
    
            defaultConverterMap.put("caller", CallerDataConverter.class.getName());
    
            defaultConverterMap.put("marker", MarkerConverter.class.getName());
    
            defaultConverterMap.put("property", PropertyConverter.class.getName());
    
            defaultConverterMap.put("n", LineSeparatorConverter.class.getName());
    
            defaultConverterMap.put("black", BlackCompositeConverter.class.getName());
            defaultConverterMap.put("red", RedCompositeConverter.class.getName());
            defaultConverterMap.put("green", GreenCompositeConverter.class.getName());
            defaultConverterMap.put("yellow", YellowCompositeConverter.class.getName());
            defaultConverterMap.put("blue", BlueCompositeConverter.class.getName());
            defaultConverterMap.put("magenta", MagentaCompositeConverter.class.getName());
            defaultConverterMap.put("cyan", CyanCompositeConverter.class.getName());
            defaultConverterMap.put("white", WhiteCompositeConverter.class.getName());
            defaultConverterMap.put("gray", GrayCompositeConverter.class.getName());
            defaultConverterMap.put("boldRed", BoldRedCompositeConverter.class.getName());
            defaultConverterMap.put("boldGreen", BoldGreenCompositeConverter.class.getName());
            defaultConverterMap.put("boldYellow", BoldYellowCompositeConverter.class.getName());
            defaultConverterMap.put("boldBlue", BoldBlueCompositeConverter.class.getName());
            defaultConverterMap.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
            defaultConverterMap.put("boldCyan", BoldCyanCompositeConverter.class.getName());
            defaultConverterMap.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
            defaultConverterMap.put("highlight", HighlightingCompositeConverter.class.getName());
    
            defaultConverterMap.put("lsn", LocalSequenceNumberConverter.class.getName());
    
        }
    
        public PatternLayout() {
            this.postCompileProcessor = new EnsureExceptionHandling();
        }
    
        public Map getDefaultConverterMap() {
            return defaultConverterMap;
        }
    
        public String doLayout(ILoggingEvent event) {
            if (!isStarted()) {
                return CoreConstants.EMPTY_STRING;
            }
            return writeLoopOnConverters(event);
        }
    
        @Override
        protected String getPresentationHeaderPrefix() {
            return HEADER_PREFIX;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110

    PatternLayout继承了PatternLayoutBase,其static方法往defaultConverterMap添加了一系列的convert

    PatternLayoutBase

    ch/qos/logback/core/pattern/PatternLayoutBase.java

    abstract public class PatternLayoutBase extends LayoutBase {
    
        static final int INTIAL_STRING_BUILDER_SIZE = 256;
        Converter head;
        String pattern;
        protected PostCompileProcessor postCompileProcessor;
        
        Map instanceConverterMap = new HashMap();
        protected boolean outputPatternAsHeader = false;
    
        //......
    
        /**
         * Concrete implementations of this class are responsible for elaborating the
         * mapping between pattern words and converters.
         * 
         * @return A map associating pattern words to the names of converter classes
         */
        abstract public Map getDefaultConverterMap();
    
        /**
         * Returns a map where the default converter map is merged with the map
         * contained in the context.
         */
        public Map getEffectiveConverterMap() {
            Map effectiveMap = new HashMap();
    
            // add the least specific map fist
            Map defaultMap = getDefaultConverterMap();
            if (defaultMap != null) {
                effectiveMap.putAll(defaultMap);
            }
    
            // contextMap is more specific than the default map
            Context context = getContext();
            if (context != null) {
                @SuppressWarnings("unchecked")
                Map contextMap = (Map) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
                if (contextMap != null) {
                    effectiveMap.putAll(contextMap);
                }
            }
            // set the most specific map last
            effectiveMap.putAll(instanceConverterMap);
            return effectiveMap;
        }    
    }    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    PatternLayoutBase继承了LayoutBase,它定义了抽象类getDefaultConverterMap,而getEffectiveConverterMap方法返回的effectiveMap则包含了defaultConverterMap,它还包含了context中key为CoreConstants.PATTERN_RULE_REGISTRY注册的,以及本身定义的instanceConverterMap

    LogbackPatternConverter

    org/apache/skywalking/apm/toolkit/log/logback/v1/x/LogbackPatternConverter.class

    public class LogbackPatternConverter extends ClassicConverter {
        public LogbackPatternConverter() {
        }
    
        public String convert(ILoggingEvent iLoggingEvent) {
            return "TID: N/A";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    LogbackPatternConverter继承了ClassicConverter,其convert方法返回TID: N/A

    ClassicConverter

    ch/qos/logback/classic/pattern/ClassicConverter.java

    abstract public class ClassicConverter extends DynamicConverter {
    
    }
    
    • 1
    • 2
    • 3

    ClassicConverter继承了DynamicConverter,其泛型为ILoggingEvent

    DynamicConverter

    ch/qos/logback/core/pattern/DynamicConverter.java

    abstract public class DynamicConverter extends FormattingConverter implements LifeCycle, ContextAware {
    
        ContextAwareBase cab = new ContextAwareBase(this);
    
        // Contains a list of option Strings.
        private List optionList;
    
        /**
         * Is this component active?
         */
        protected boolean started = false;
    
        /**
         * Components that depend on options passed during configuration can override
         * this method in order to make appropriate use of those options. For simpler
         * components, the trivial implementation found in this abstract class will be
         * sufficient.
         */
        public void start() {
            started = true;
        }
    
        public void stop() {
            started = false;
        }
    
        public boolean isStarted() {
            return started;
        }
    
        public void setOptionList(List optionList) {
            this.optionList = optionList;
        }
    
        /**
         * Return the first option passed to this component. The returned value may be
         * null if there are no options.
         * 
         * @return First option, may be null.
         */
        public String getFirstOption() {
            if (optionList == null || optionList.size() == 0) {
                return null;
            } else {
                return optionList.get(0);
            }
        }
    
        protected List getOptionList() {
            return optionList;
        }
    
        public void setContext(Context context) {
            cab.setContext(context);
        }
    
        public Context getContext() {
            return cab.getContext();
        }
    
        public void addStatus(Status status) {
            cab.addStatus(status);
        }
    
        public void addInfo(String msg) {
            cab.addInfo(msg);
        }
    
        public void addInfo(String msg, Throwable ex) {
            cab.addInfo(msg, ex);
        }
    
        public void addWarn(String msg) {
            cab.addWarn(msg);
        }
    
        public void addWarn(String msg, Throwable ex) {
            cab.addWarn(msg, ex);
        }
    
        public void addError(String msg) {
            cab.addError(msg);
        }
    
        public void addError(String msg, Throwable ex) {
            cab.addError(msg, ex);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    DynamicConverter继承了FormattingConverter,声明实现LifeCycle, ContextAware接口

    FormattingConverter

    ch/qos/logback/core/pattern/FormattingConverter.java

    abstract public class FormattingConverter extends Converter {
    
        static final int INITIAL_BUF_SIZE = 256;
        static final int MAX_CAPACITY = 1024;
    
        FormatInfo formattingInfo;
    
        final public FormatInfo getFormattingInfo() {
            return formattingInfo;
        }
    
        final public void setFormattingInfo(FormatInfo formattingInfo) {
            if (this.formattingInfo != null) {
                throw new IllegalStateException("FormattingInfo has been already set");
            }
            this.formattingInfo = formattingInfo;
        }
    
        @Override
        final public void write(StringBuilder buf, E event) {
            String s = convert(event);
    
            if (formattingInfo == null) {
                buf.append(s);
                return;
            }
    
            int min = formattingInfo.getMin();
            int max = formattingInfo.getMax();
    
            if (s == null) {
                if (0 < min)
                    SpacePadder.spacePad(buf, min);
                return;
            }
    
            int len = s.length();
    
            if (len > max) {
                if (formattingInfo.isLeftTruncate()) {
                    buf.append(s.substring(len - max));
                } else {
                    buf.append(s.substring(0, max));
                }
            } else if (len < min) {
                if (formattingInfo.isLeftPad()) {
                    SpacePadder.leftPad(buf, s, min);
                } else {
                    SpacePadder.rightPad(buf, s, min);
                }
            } else {
                buf.append(s);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    FormattingConverter继承了Converter,它定义了formattingInfo属性,其write方法根据formattingInfo信息进行append

    示例

        
    
             
            
                
                    ${PATTERN_DEFAULT}
                
            
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里采用了TraceIdPatternLogbackLayout,并在pattern中使用了tid

    小结

    skywalking的apm-toolkit-logback-1.x组件提供了TraceIdPatternLogbackLayout,可以在日志中打印tid。

  • 相关阅读:
    数据通信——传输层TCP(超时时间选择)
    【分享】订阅金蝶云进销存集简云连接器同步销货数据至金蝶云进销存系统
    【多线程】深入剖析线程池的应用
    卓岚联网模块连接三菱FX系列PLC应用实例
    NEON优化:性能优化经验总结
    MySQL8.0安装教程
    springboot+美容院会员管理系统 毕业设计-附源码191740
    ExoPlayer架构详解与源码分析(7)——SampleQueue
    Ros noetic 机器人坐标记录运动路径和发布 实战教程(B)
    Groovy(第五节) Groovy 之集合
  • 原文地址:https://blog.csdn.net/hello_ejb3/article/details/134545754