1 概述
logback.xml配置文件的详细配置,很多地方都说得比较细,本文主要从几个重点来看一下原理,了解原理能够帮助确定哪些应该配置,以及如何配置。
logback.xml是为打印日志服务的,打印的内容一般打印到控制台(Console)和文件(file)里,在生产环境中主要是打印到文件里,然后用扫描工具汇总到某个地方方便查询(如ELK)。打印的内容要符合一定的格式,提供足够的信息,方便进行日志查询和分析;如果所有日志都打印到一个文件里,就有可能文件过大而难以查看,还可能大到一个磁盘装不下,也很难把早期的日志删除掉仅保留一定期限内的日志,所以需要对日志文件进行拆分,每个文件确定在一定大小之内,并控制总体仅保留一定量的日志,避免日志总量过多把磁盘占满了宕机等。日志配置文件也不是一成不变的,当修改了配置文件,希望能够不需要重启Java进程而能够生效,比如修改日志级别。
2 原理
2.1 打印内容的格式
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) [%thread] %logger{50} - %msg%n</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>

上面就是一个<appender>的配置,里面的<Pattern>就是日志内容的格式,还可以设置高亮颜色。如果要详细看logback支持的格式,那么可以参考官方文档:https://logback.qos.ch/manual/layouts.html
如果想了解原理也容易,上面就指明了对应的类ch.qos.logback.classic.encoder.PatternLayoutEncoder,这也代表着甚至可以通过它来自定义。
// 当加载logback.xml文件时,解析到<encoder>节点的时候,会调PatternLayoutEncoder.start()
// 源码位置:ch.qos.logback.classic.encoder.PatternLayoutEncoder
public class PatternLayoutEncoder extends PatternLayoutEncoderBase<ILoggingEvent> {
public PatternLayoutEncoder() {
}
public void start() {
// 1. 初始化PatternLayout,里面会初始化一些Converter
PatternLayout patternLayout = new PatternLayout();
patternLayout.setContext(this.context);
patternLayout.setPattern(this.getPattern());
patternLayout.setOutputPatternAsHeader(this.outputPatternAsHeader);
patternLayout.start();
this.layout = patternLayout;
super.start();
}
}
// 源码位置:ch.qos.logback.classic.PatternLayout
// 2. 静态代码块初始化converter,它们决定了<Pattern>节点里能够配置的变量,用%来指示变量,比如%d表示时间
public static final Map<String, String> DEFAULT_CONVERTER_MAP = new HashMap<String, String>();
static {
DEFAULT_CONVERTER_MAP.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
DEFAULT_CONVERTER_MAP.put("d", DateConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("date", DateConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("r", RelativeTimeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("relative", RelativeTimeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("level", LevelConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("le", LevelConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("p", LevelConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("t", ThreadConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("thread", ThreadConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("lo", LoggerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("logger", LoggerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("c", LoggerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("m", MessageConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("msg", MessageConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("message", MessageConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("C", ClassOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("class", ClassOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("M", MethodOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("method", MethodOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("L", LineOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("line", LineOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("F", FileOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("file", FileOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("X", MDCConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("mdc", MDCConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("ex", ThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("exception", ThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("rEx", RootCauseFirstThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("rootException", RootCauseFirstThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("throwable", Throwab

最低0.47元/天 解锁文章
1342

被折叠的 条评论
为什么被折叠?



