TraceIdPatternLogbackLayout日志拦截源码解析
作者:codecraft
这篇文章主要为大家介绍了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()); } }
skywalking的TraceIdPatternLogbackLayout继承了PatternLayout,其static方法往defaultConverterMap添加了tid,value为LogbackPatternConverter.class.getName()
PatternLayout
ch/qos/logback/classic/PatternLayout.java
public class PatternLayout extends PatternLayoutBase<ILoggingEvent> { public static final Map<String, String> defaultConverterMap = new HashMap<String, String>(); 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<String, String> getDefaultConverterMap() { return defaultConverterMap; } public String doLayout(ILoggingEvent event) { if (!isStarted()) { return CoreConstants.EMPTY_STRING; } return writeLoopOnConverters(event); } @Override protected String getPresentationHeaderPrefix() { return HEADER_PREFIX; } }
PatternLayout继承了PatternLayoutBase,其static方法往defaultConverterMap添加了一系列的convert
PatternLayoutBase
ch/qos/logback/core/pattern/PatternLayoutBase.java
abstract public class PatternLayoutBase<E> extends LayoutBase<E> { static final int INTIAL_STRING_BUILDER_SIZE = 256; Converter<E> head; String pattern; protected PostCompileProcessor<E> postCompileProcessor; Map<String, String> instanceConverterMap = new HashMap<String, String>(); 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<String, String> getDefaultConverterMap(); /** * Returns a map where the default converter map is merged with the map * contained in the context. */ public Map<String, String> getEffectiveConverterMap() { Map<String, String> effectiveMap = new HashMap<String, String>(); // add the least specific map fist Map<String, String> 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<String, String> contextMap = (Map<String, String>) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY); if (contextMap != null) { effectiveMap.putAll(contextMap); } } // set the most specific map last effectiveMap.putAll(instanceConverterMap); return effectiveMap; } }
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"; } }
LogbackPatternConverter继承了ClassicConverter,其convert方法返回TID: N/A
ClassicConverter
ch/qos/logback/classic/pattern/ClassicConverter.java
abstract public class ClassicConverter extends DynamicConverter<ILoggingEvent> { }
ClassicConverter继承了DynamicConverter,其泛型为ILoggingEvent
DynamicConverter
ch/qos/logback/core/pattern/DynamicConverter.java
abstract public class DynamicConverter<E> extends FormattingConverter<E> implements LifeCycle, ContextAware { ContextAwareBase cab = new ContextAwareBase(this); // Contains a list of option Strings. private List<String> 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<String> 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<String> 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); } }
DynamicConverter继承了FormattingConverter,声明实现LifeCycle, ContextAware接口
FormattingConverter
ch/qos/logback/core/pattern/FormattingConverter.java
abstract public class FormattingConverter<E> extends Converter<E> { 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); } } }
FormattingConverter继承了Converter,它定义了formattingInfo属性,其write方法根据formattingInfo信息进行append
示例
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%thread] [%tid] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <pattern>${PATTERN_DEFAULT}</pattern> </layout> </encoder> </appender>
这里采用了TraceIdPatternLogbackLayout,并在pattern中使用了tid
小结
skywalking的apm-toolkit-logback-1.x组件提供了TraceIdPatternLogbackLayout,可以在日志中打印tid。
以上就是TraceIdPatternLogbackLayout的详细内容,更多关于TraceIdPatternLogbackLayout的资料请关注脚本之家其它相关文章!
以上就是TraceIdPatternLogbackLayout日志拦截源码解析的详细内容,更多关于TraceIdPatternLogbackLayout日志拦截的资料请关注脚本之家其它相关文章!