1.什么是appender?
logback 将写入日志事件的任务委托给一个名为 appender 的组件。Appender 必须实现ch.qos.logback.core.Appender 接口, appender 的组件有两个属性:name和class,并且需要强制赋值,解释如下:
name: 定义写日志组件的唯一名称,可以随便定义。如:INFO-LOG、ERROR-LOG、WARN-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.out 或 System.err。默认为 System.out |
| withJansi | boolean | withJansi 的默认值为 false。设置 withJansi 为 true 可以激活 Jansi 在 windows 使用 ANSI 彩色代码。在 windows 上如果设置为 true,你应该将 org.fusesource.jansi:jansi:1.9 这个 jar 包放到 classpath 下。基于 Unix 实现的操作系统,像 Linux、Max OS X 都默认支持 ANSI 才彩色代码。 |
2.配置示例
|
2. 2 FileAppender
FileAppender是 OutputStreamAppender 的子类,将日志事件输出到文件中。通过 file 来指定目标文件。如果该文件存在,根据 append 的值,要么将日志追加到文件中,要么该文件被截断。
1.标签属性
| 属性名 | 类型 | 描述 |
|---|---|---|
| append | boolean | 如果为 true,日志事件会被追加到文件中,否则的话,文件会被截断。默认为 true |
| encoder | Encoder |
参见 ConsoleAppender 的属性 |
| file | String | 要写入文件的名称。如果文件不存在,则新建。 |
| prudent | boolean | 在严格模式下,FileAppender 会将日志安全的写入指定文件。即使在不同的 JVM 或者不同的主机上运行 FileAppender 实例。默认的值为 false。 严格模式可以与 RollingFileAppender 结合使用。 |
2.配置示例
|
2.3 RollingFileAppender
RollingFileAppender 继承自FileAppender,具有轮转日志文件的功能。当满足某个特定的条件之后,将日志输出到另外一个文件。
1. RollingPolicy滚动策略
RollingPolicy滚动策略包括以下几种:
TimeBasedRollingPolicy: 基于时间的滚动策略SizeAndTimeBasedRollingPolicy: 基于时间和文件大小的滚动策略FixedWindowRollingPolicy: 基于窗口大小的滚动策略,说白了就是将归档日志文件到最大了就写到下一个文件里,而窗口大小就是最多允许多少份日志文件。
2. TimeBasedRollingPolicy
TimeBasedRollingPolicy 是最常用的轮转策略。它是基于时间来定义轮转策略。例如按天或者按月。TimeBasedRollingPolicy 既负责轮转的行为,也负责触发轮转。实际上,TimeBasedRollingPolicy 同时实现了 RollingPolicy 与 TriggeringPolicy 接口。
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 启动的时候执行删除操作。 |
配置示例:
|
3. SizeAndTimeBasedRollingPolicy
SizeAndTimeBasedRollingPolicy 既可以按时轮转,又能限制每个日志文件的大小。
配置示例:
|
4. FixedWindowRollingPolicy
在轮转时,FixedWindowRollingPolicy 根据固定窗口算法重命名文件,具体描述如下:
filaNamePattern 表示归档文件的名字。这个属性是必须的,而且必须包含一个表示整形的占位符 i%。
FixedWindowRollingPolicy 的可用属性如下:
| 属性名 | 类型 | 描述 |
|---|---|---|
| minIndex | int | 表示窗口索引的下界 |
| maxIndex | int | 表示窗口索引的上界 |
| fileNamePattern | String | FixedWindowRollingPolicy 在重命名日志文件时将会根据这个属性来命名。它必须包含一个 i% 的占位符,该占位符指明了窗口索引的值应该插入的位置。 例如,当该属性的值为 MyLogFile%i.log,最小与最大的值分别为 1 和 3。将会产生的归档文件为 MyLogFile1.log,MyLogFile2.log,MyLogFile3.log。 文件压缩的方式也是通过该属性来指定。例如,设置该属性的值为 MyLogFile%i.log.zip,那么归档文件将会被压缩成 zip 格式。也可以选择压缩成 gz 格式。 |
配置示例:
|
5. 轮转周期示例(fileNamePattern)
适用上面SizeAndTimeBasedRollingPolicy、 TimeBasedRollingPolicy 滚动策略<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 基于级别来过滤日志事件。如果事件的级别与配置的级别相等,过滤器会根据配置的 onMatch 与 onMismatch 属性,接受或者拒绝事件。如下是一个简单的示例:
配置示例:
|
3.2 ThresholdFilter
ThresholdFilter 基于给定的临界值来过滤事件。如果事件的级别等于或高于给定的临界值,当调用 decide() 时,ThresholdFilter 将会返回 NEUTRAL。但是事件的级别低于临界值将会被拒绝。下面是一个简单的例子:
|








