Logback : layout 写法(官方文档总结)

1,378 阅读3分钟

首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 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} 控制长度

image.png

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") &amp;&amp; \
            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 中最小的一环,只是了解一下用法,后续有空再看看源码吧。