首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…
一. 前言
算是一篇翻译文档吧,最近在了解 logback 的深度用法 ,所以看了下官方文档 ,看了不能白看,来都来了,把核心概念稍微记录下。
官方文档 @ logback.qos.ch/manual/inde…
二. layout 核心
layout 就是通常从网上copy一个配置后,大概率要改的那个地方 。 通常我们在网上找的 logback 配置文件主要长这样 :
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 自定义 layout -->
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="chapters.layouts.MySampleLayout" />
</encoder>
<!-- pattern -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern>
<charset>${log.charset}</charset>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
从这个模板中可以看到2种 layout 的配置方式。其中我们最常用的应该是基于 Pattern 的模式,在极特殊的场景下,才会使用到自定义 layout 的模式。
2.1 常见 layout 的用法
logback 提供了很多常见的 layout , 最常用的几种包括 : PatternLayout / HTMLLayout / XMLLayout 等。
2.2 自定义 layout
自定义 layout 应用场景不算多,但是一定是有的,列举几个常用的包括 :
- 敏感信息脱敏 : 这是最常见的场景,对于密码手机等信息,我们不期望打印到日志中。
- 定制化日志输出格式 : 这是 layout 的目的 ,但是通常单纯为了格式不会专门定制 layout,徒增耦合
- 日志分类格式输出 :这种就属于更复杂的场景了,主要配合 event 进行控制,通过里面的参数来打印不同格式的日志
public class MySampleLayout extends LayoutBase<ILoggingEvent> {
public String doLayout(ILoggingEvent event) {
StringBuffer sbuf = new StringBuffer(128);
sbuf.append(event.getTimeStamp() - event.getLoggingContextVO.getBirthTime());
return sbuf.toString();
}
}
三. pattern 写法
3.1 变量占位符
- 通过 {length} 控制长度
3.2 格式控制
- 格式控制的目的在于保证长度输出样式的统一
// 长度控制
- %20logger :最小长度20,内容左对齐 > [ main.Name]
- %-20logger : 最小长度20,内容右对齐 > [main.Name ]
- %.30logger : 最大30个字符,多余截断
- %10.30logger :最小长度10,最大长度30 > [o.bar.Name]
- %.-30logger : 从末尾截断
- 分组 : 通过括号可以对多个变量进行分组
// 此处如果 %d{HH:mm:ss.SSS} [%thread] 不足30 , 会自动扩展到30
%-30(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{32} - %msg%n
> 例如 :
13:09:30 [main] DEBUG c.q.logback.demo.;ContextListener - Classload hashcode is 13995234
- 分组后
13:09:30 [main] DEBUG c.q.logback.demo.;ContextListener - Classload hashcode is 13995234
- 为日志设置颜色
// 允许设置的颜色
"%black", "%red", "%green","%yellow","%blue", "%magenta","%cyan",
"%white", "%gray", "%boldRed","%boldGreen", "%boldYellow",
"%boldBlue", "%boldMagenta""%boldCyan", "%boldWhite" and "%highlight"
// 使用方式
[%thread] %highlight(%-5level) %cyan(%logger{15})
3.3 高级用法
Evaluators
Evaluators 模块除了在 Filter 里面可以使用外,本身也可以作为 pattern 的变量成员使用 :
<configuration>
<evaluator name="DISP_CALLER_EVAL">
<expression>logger.contains("chapters.layouts") && \
message.contains("who calls thee")</expression>
</evaluator>
<appender name="STDOUT" class="ch.qos.logback.;core.ConsoleAppender">
<encoder>
<!-- 这里引用上文的 DISP_CALLER_EVAL -->
<pattern>
%-4relative [%thread] %-5level -%kvp -%msg%n%caller{2, DISP_CALLER_EVAL}
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
自定义 Convert
public class MySampleConverter extends ClassicConverter {
// 此处返回了一个时间
@Override
public String convert(ILoggingEvent event) {
return Long.toString(System.nanoTime());
}
}
<configuration>
<conversionRule conversionWord="nanos"
converterClass="chapters.;layouts.MySampleConverter" />
<appender name="STDOUT" class="ch.qos.logback.;core.ConsoleAppender">
<encoder>
<!-- 上面对conversion进行了配置,然后在此处使用-->
<pattern>%-6nanos [%thread] -%kvp -%msg%n</pattern>
</encoder>
</appender>
</configuration>
其他layout
其他附带的 layout 包括 HTMLLayout 和 XMLLayout
<appender name="FILE" class="ch.qos.logback.;core.FileAppender">
<encoder class="ch.qos.logback.;core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.;classic.html.HTMLLayout">
<pattern>%relative%thread%mdc%level%logger%msg</pattern>
</layout>
</encoder>
<file>test.html</file>
</appender>
其中 %relative%thread%mdc%level%logger%msg 这一段会形成一个表格 ,relative 就是表头。不过这种方式使用的场景比较少。
四. 思路扩展 : 有哪些应用场景
首先从变量角度来说,有很多变量可以组合出复杂的业务场景。例如 :
- 可以通过 %ex 等变量控制异常的打印,在部分业务代码种,异常栈太长会影响业务的跟踪
- 打印出你的日志线程有助于在多线程场景下排查问题
- 通过分组和长度控制,让日志的展示更加美观
对于使用日志收集框架来说,本质上 XML 没有太多的玩法。
总结
layout 毕竟只是 logback 中最小的一环,只是了解一下用法,后续有空再看看源码吧。