1.什么是appender?

logback 将写入日志事件的任务委托给一个名为 appender 的组件。Appender 必须实现ch.qos.logback.core.Appender 接口, appender 的组件有两个属性:nameclass,并且需要强制赋值,解释如下:

  • name: 定义写日志组件的唯一名称,可以随便定义。如:INFO-LOGERROR-LOGWARN-LOG
  • class: 一个Appender种类实例的完整类名称。

appender种类有很多,常用的种类有:ConsoleAppender、FileAppender、RollingFileAppender。

2. appender种类介绍

2.1 ConsoleAppender

ConsoleAppender 就跟名字显示的一样,是将日志事件附加到控制台,进一步说就是通过 System.out 或者 System.err 来进行输出,默认通过前者ConsoleAppender 通过用户指定的 encoder,格式化日志事件。

1.标签属性

属性名 类型 描述
encoder Encoder 决定通过哪种方式将事件写入 OutputStreamAppender
target String System.outSystem.err。默认为 System.out
withJansi boolean withJansi 的默认值为 false。设置 withJansitrue 可以激活 Jansi 在 windows 使用 ANSI 彩色代码。在 windows 上如果设置为 true,你应该将 org.fusesource.jansi:jansi:1.9 这个 jar 包放到 classpath 下。基于 Unix 实现的操作系统,像 Linux、Max OS X 都默认支持 ANSI 才彩色代码。

2.配置示例

<configuration>
<!--日志输出器-->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默认使用 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%date %-5level-[%thread] %class.%method|%line : %msg%n</pattern>
</encoder>
</appender>
<!-- 根记录器 -->
<root level="info">
<!--输出记录的日志-->
<appender-ref ref="CONSOLE-LOG"/>
</root>
</configuration>

2. 2 FileAppender

FileAppenderOutputStreamAppender 的子类,将日志事件输出到文件中。通过 file 来指定目标文件。如果该文件存在,根据 append 的值,要么将日志追加到文件中,要么该文件被截断。

1.标签属性

属性名 类型 描述
append boolean 如果为 true,日志事件会被追加到文件中,否则的话,文件会被截断。默认为 true
encoder Encoder 参见 ConsoleAppender 的属性
file String 要写入文件的名称。如果文件不存在,则新建。
prudent boolean 在严格模式下,FileAppender 会将日志安全的写入指定文件。即使在不同的 JVM 或者不同的主机上运行 FileAppender 实例。默认的值为 false。 严格模式可以与 RollingFileAppender 结合使用。

2.配置示例

<configuration>
<!-- 通过 "bySecond" 将时间格式化成 "yyyyMMdd'T'HHmmss" 的形式插入到 logger 的上下文中这个值对后续的配置也适用-->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- 利用之前创建的 timestamp 来创建唯一的文件 -->
<!-- 生成的文件名: log-20201029T122403.log -->
<file>logs/log-${bySecond}.log</file>
<!-- 将 immediateFlush 设置为 false 可以获得更高的日志吞吐量 -->
<immediateFlush>true</immediateFlush>
<!-- 默认为 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%date %-5level -[%thread] %class.%method/%line : %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>

2.3 RollingFileAppender

RollingFileAppender 继承自FileAppender,具有轮转日志文件的功能。当满足某个特定的条件之后,将日志输出到另外一个文件。

1. RollingPolicy滚动策略

RollingPolicy滚动策略包括以下几种:

  • TimeBasedRollingPolicy: 基于时间的滚动策略
  • SizeAndTimeBasedRollingPolicy: 基于时间和文件大小的滚动策略
  • FixedWindowRollingPolicy: 基于窗口大小的滚动策略,说白了就是将归档日志文件到最大了就写到下一个文件里,而窗口大小就是最多允许多少份日志文件。

2. TimeBasedRollingPolicy

TimeBasedRollingPolicy 是最常用的轮转策略。它是基于时间来定义轮转策略。例如按天或者按月。TimeBasedRollingPolicy 既负责轮转的行为,也负责触发轮转。实际上,TimeBasedRollingPolicy 同时实现了 RollingPolicyTriggeringPolicy 接口。

TimeBasedRollingPolicy 的配置需要一个强制的属性 fileNamePattern 以及其它的可选属性。

属性名 类型 描述
fileNamePattern String 该属性的值应该由文件名加上一个 %d的占位符。%d 应包含 java.text.SimpleDateFormat 中规定的日期格式。如果省略日期格式,那么就默认为 yyyy-MM-dd。如果 fileNamePattern.gz 或者 .zip 结尾,将会启动这个特性。
maxHistory int 这个可选的属性用来控制最多保留多少数量的归档文件,将会异步删除旧的文件。如单位按月轮转时maxHistory = 6,只会保留6个月的日志。单位根据时间格式维度来区分:按天(yyyy-MM-dd)/按月(yyyy-MM)
totalSizeCap int 在有 maxHistory 的限制下,进一步限制所有日志文件大小之和的上限,超过则从最旧的日志开始删除
cleanHistoryOnStart boolean 如果设置为 true,那么在 appender 启动的时候,归档文件将会被删除。默认的值为 false。 归档文件的删除通常在轮转期间执行。但是,有些应用的存活时间可能等不到轮转触发。对于这种短期应用,可以通过设置该属性为 true,在 appender 启动的时候执行删除操作。

配置示例:

<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<!-- 启用基于时间的滚动策略:TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 设置轮转策略为: 每分钟轮转-->
<fileNamePattern>logs/app_%d{yyyy-MM-dd HH:mm}.log</fileNamePattern>
<!-- 只保留最近10分钟内的日志-->
<maxHistory>10</maxHistory>
<!-- 所有日志文件大小之和的上限-->
<totalSizeCap>1MB</totalSizeCap>
<!--在 appender 启动的时候执行删除历史日志操作-->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<!-- 默认为 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%date %-5level -[%thread] %class.%method/%line : %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING"/>
</root>
</configuration>

3. SizeAndTimeBasedRollingPolicy

SizeAndTimeBasedRollingPolicy 既可以按时轮转,又能限制每个日志文件的大小。

配置示例:

<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 活动中的日志文件名(支持绝对和相对路径) -->
<file>logs/app.log</file>
<!-- 基于时间和文件大小的滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 设置轮转策略为: 每小时轮转 -->
<fileNamePattern>logs/app_%d{yyyy-MM-dd HH}_%i.zip</fileNamePattern>
<!--单个日志文件的最大大小-->
<maxFileSize>1MB</maxFileSize>
<!-- 根据当前轮转策略,只保留最近3小时内的日志-->
<maxHistory>3</maxHistory>
<!-- 所有日志文件大小之和的上限-->
<totalSizeCap>200MB</totalSizeCap>
<!-- 在只有设置为true并且 maxHistory 不为零才能起效-->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<!-- 日志输出格式 -->
<pattern>%date %-5level -[%thread] %class.%method/%line : %msg%n</pattern>
</encoder>
</appender>
<!-- 根记录器 -->
<root level="info">
<appender-ref ref="ROLLING"/>
</root>
</configuration>

4. FixedWindowRollingPolicy

在轮转时,FixedWindowRollingPolicy 根据固定窗口算法重命名文件,具体描述如下:

filaNamePattern 表示归档文件的名字。这个属性是必须的,而且必须包含一个表示整形的占位符 i%

FixedWindowRollingPolicy 的可用属性如下:

属性名 类型 描述
minIndex int 表示窗口索引的下界
maxIndex int 表示窗口索引的上界
fileNamePattern String FixedWindowRollingPolicy 在重命名日志文件时将会根据这个属性来命名。它必须包含一个 i% 的占位符,该占位符指明了窗口索引的值应该插入的位置。 例如,当该属性的值为 MyLogFile%i.log,最小与最大的值分别为 13。将会产生的归档文件为 MyLogFile1.logMyLogFile2.logMyLogFile3.log。 文件压缩的方式也是通过该属性来指定。例如,设置该属性的值为 MyLogFile%i.log.zip,那么归档文件将会被压缩成 zip 格式。也可以选择压缩成 gz 格式。

配置示例:

<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app_aa.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/app_aa.%i.log.gz</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>5</maxIndex>
</rollingPolicy>
<!--SizeBasedTriggeringPolicy 观察当前活动文件的大小,如果已经大于了指定的值,它会给 RollingFileAppender 发一个信号触发对当前活动文件的轮转 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>10KB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%date %-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>

<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>

5. 轮转周期示例(fileNamePattern)

适用上面SizeAndTimeBasedRollingPolicyTimeBasedRollingPolicy 滚动策略<fileNamePattern></fileNamePattern>

fileNamePattern 格式 说明
app_%d.log 每天轮转。不指定%d日期格式时默认为 yyyy-MM-dd
app_%d{yyyy-MM}.log 每个月开始的时候轮转
app._%d{yyyy-ww}.log 每周的第一天(取决于时区)
app_%d{yyyy-MM-dd_HH}.log 每小时轮转; 如:app_2020-10-24_10.log
app_%d{yyyy-MM-dd_HH-mm}.log 每分钟轮转; 如:app_2020-10-24_10-32.log
app_%d{yyyy-MM-dd_HH-mm, UTC}.log 每分钟轮转(时间格式是 UTC);
app/%d{yyyy-MM}/%d.log 每天轮转。第一个%d被辅助标记。第二个%d为主要标记。如:app/2020-10/2020-10-24.log

3. 过滤器(Filters)

filter其实是appender里面的子元素。它作为过滤器存在,执行一个过滤器会有返回DENY,NEUTRAL,ACCEPT三个枚举值中的一个。appender 有多个过滤器时,按照配置顺序执行。

  • DENY: 日志将立即被抛弃不再经过其他过滤器。
  • NEUTRAL: 有序列表里的下个过滤器过接着处理日志。
  • ACCEPT: 日志会被立即处理,不再经过剩余过滤器。

3.1 LevelFilter

LevelFilter 基于级别来过滤日志事件。如果事件的级别与配置的级别相等,过滤器会根据配置的 onMatchonMismatch 属性,接受或者拒绝事件。如下是一个简单的示例:

配置示例:

<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--只显示INFO级别日志 -->
<level>INFO</level>
<!--INFO级别的日志, 被立即执行不再经过其他过滤器-->
<onMatch>ACCEPT</onMatch>
<!--不是INFO级别的日志, 立即被抛弃不再经过其他过滤器-->
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>
%-4relative [%thread] %-5level %logger{30} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

3.2 ThresholdFilter

ThresholdFilter 基于给定的临界值来过滤事件。如果事件的级别等于或高于给定的临界值,当调用 decide() 时,ThresholdFilter 将会返回 NEUTRAL。但是事件的级别低于临界值将会被拒绝。下面是一个简单的例子:

<configuration>
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<!-- 拒绝低于 INFO的日志, RACE and DEBUG,但是会显示WARN和ERROR级别日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>
%-4relative [%thread] %-5level %logger{30} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

文档推荐

logback中文文档(http://www.logback.cn/)