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。但是事件的级别低于临界值将会被拒绝。下面是一个简单的例子:
|