一、appender类型介绍
OutputStreamAppender
- 你不能通过配置文件配置一个 OutputStreamAppender
- OutputStreamAppender 是其他三个 appender 的父类,分别是 ConsoleAppender、FileAppender 以及 RollingFileAppender。FileAppender 又是 RollingFileAppender 的父类
OutputStreamAppender属性列表
属性名 | 属性值 | 描述 |
---|---|---|
ecoder | Encoder |
决定通过哪种方式将事件写入 OutputStreamAppender ,Encoder 将会在单独的章节介绍 |
immediateFlush | boolean |
immediateFlush 的默认值为 true。立即刷新输出流可以确保日志事件被立即写入,并且可以保证一旦你的应用没有正确关闭 appender,日志事件也不会丢失。从另一方面来说,设置这个属性为 false,有可能会使日志的吞吐量翻两番(视情况而定)。但是,设置为 false,当应用退出的时候没有正确关闭 appender,会导致日志事件没有被写入磁盘,可能会丢失。 |
OutputStreamAppender 与子类之间的关系
ConsoleAppender
ConsoleAppender
就跟名字显示的一样,是将日志事件附加到控制台,跟进一步说就是通过 System.out 或者 System.err 来进行输出。默认通过前者。
属性名 | 类型 | 描述 |
---|---|---|
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 才彩色代码。 |
例子
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender" >
<!-- encoder 默认使用 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
FileAppender
属性名 | 类型 | 描述 |
---|---|---|
append | boolean | 如果为 true ,日志事件会被追加到文件中,否则的话,文件会被截断。默认为 true
|
encoder | Encoder |
参见 OutputStreamAppender 的属性 |
file | String | 要写入文件的名称。如果文件不存在,则新建。在 windows 平台上,用户经常忘记对反斜杠进行转义。例如,c:\temp\test.log 不会被正确解析,因为 '\t' 是一个转义字符,会被解析为一个 tab 字符 (\u0009)。正确的值应该像:c:/temp/test.log 或者 c:\temp\test.log。没有默认值。 |
prudent | boolean | 在严格模式下,FileAppender 会将日志安全的写入指定文件。即使在不同的 JVM 或者不同的主机上运行 FileAppender 实例。默认的值为 false 。严格模式可以与 RollingFileAppender 结合使用。严格模式也意味着 append 属性被自动设置为 true 。严格模式依赖排他文件锁。实验证明,文件锁大概是写入日志事件成本的 3 倍。在严格模式关闭的情况下,往一台"普通"电脑的硬盘上将一个日志事件写入文件,大概需要耗费 10 微秒。但是在开启的情况下,大概需要 30 微秒。也就是说在关闭的情况下可以一秒钟写入 100'000 个日志事件,但是在开启的情况下,一秒钟只能写入33'000 个日志事件。 严格模式可以在所有 JVM 写入同一个文件时,有效的序列化 I/O 操作。因此,随着竞相访问同一个文件的 JVM 数量上升,将会延迟每一个 I/O 操作。只要总共的 I/O 操作大约为每秒 20 个日志请求,对性能的影响可以被忽略。但是,如果应用每秒产生了 100 个以上的 I/O 操作,性能会受到明显的影响,应该避免使用严格模式。 网络文件锁 当日志文件位于网络文件系统上时,严谨模式的成本会更高。同样重要的是,网络文件系统的文件锁带有很强的偏向性,当前获得锁的进程在释放锁之后会立马又重新获得。因此,当一个进程独占日志文件,将会导致其它进程饥饿死锁。严格模式的影响严重依赖网速以及操作系统实现的细节。我们提供了一个小型应用 FileLockSimulator 用于在你的环境中模拟严格模式。 |
prudent | boolean | immediateFlush 默认值true,立即输出,更改为false可以显著的增加日志的吞吐率 |
用例
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<!-- 将 immediateFlush 设置为 false 可以获得更高的日志吞吐量 -->
<immediateFlush>true</immediateFlush>
<!-- 默认为 ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
RollingFileAppender
RollingFileAppender
继承自FileAppender
,具有轮转日志文件的功能。例如,RollingFileAppender
将日志输出到 log.txt 文件,在满足了特定的条件之后,将日志输出到另外一个文件。
RollingFileAppender
的属性如下所示:
属性名 | 类型 | 描述 |
---|---|---|
file | String | 参见 FileAppender
|
append | boolean | 参见 FileAppender
|
encoder | Encoder |
参见 OutputStreamAppender
|
rollingPolicy | RollingPolicy | 当轮转发生时,指定 RollingFileAppender 的行为。下面将会详细说明 |
triggeringPolicy | TriggeringPolicy | 告诉 RollingFileAppender 什么时候发生轮转行为。下面将会详细说明 |
prudent | boolean |
FixedWindowRollingPolicy 不支持该属性。RollingFileAppender 在使用严格模式时要与 TimeBasedRollingPolicy 结合使用,但是有两个限制:1. 在严格模式下,也不支持也不允许文件压缩(我们不能让一个 JVM 在写入文件时,另一个 JVM 在压缩该文件) 2. 不能对 FileAppender 的 file 属性进行设置。实际上,大多数的操作系统不允许在有进程操作文件的情况下对文件改名 |
Rolling policy 简介
RollingPolicy
负责轮转的方式为:移动文件以及对文件改名。
RollingPolicy
负责轮转的方式为:移动文件以及对文件改名。
RollingPolicy
接口如下:
package ch.qos.logback.core.rolling;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.spi.LifeCycle;
public interface RollingPolicy extends LifeCycle {
public void rollover() throws RolloverFailure;
public String getActiveFileName();
public CompressionMode getCompressionMode();
public void setParent(FileAppender appender);
}
rollover
方法负责对日志文件进行归档。getActiveFileName()
方法负责获取当前日志文件的名字。getCompressionMode
方法决定采取哪种压缩模式。通过 setParent
方法引用父类。
TimeBasedRollingPolicy
TimeBasedRollingPolicy
是最常用的轮转策略。它是基于时间来定义轮转策略。例如按天或者按月。TimeBasedRollingPolicy
既负责轮转的行为,也负责触发轮转。实际上,TimeBasedRollingPolicy
同时实现了 RollingPolicy
与 TriggeringPolicy
接口。
TimeBasedRollingPolicy
的配置需要一个强制的属性 fileNamePattern
以及其它的可选属性。
属性名 | 类型 | 描述 |
---|---|---|
fileNamePattern | String | 该属性定义了轮转时的属性名。它的值应该由文件名加上一个 %d 的占位符。%d 应该包含 java.text.SimpleDateFormat 中规定的日期格式。如果省略掉这个日期格式,那么就默认为 yyyy-MM-dd。轮转周期是通过 fileNamePattern 推断出来的。 注意:可以选择对 RollingFileAppender (TimeBasedRollingPolicy 的父类)中的 file 属性进行设置,也可以忽略。通过设置 FileAppender 的 file 属性,你可以将当前活动日志的路径与归档日志的路径分隔开来。当前日志永远会是通过 file 指定的文件。它的名字不会随着时间的推移而发生变化。但是,如果你选择忽略 file 属性,当前活动日志在每个周期内将会根据 fileNamePattern 的值变化。稍后的例子将会说明这一点。%d{} 中的日期格式将会遵循 java.text.SimpleDateFormat 中的约定。斜杆 '/' 或者反斜杠 '' 都会被解析成目录分隔符。 指定多个 %d 可以指定多个 %d,但是只能有一个是主要的,用于推断轮转周期。其它的 %d 占位符必须通过 'aux' 标记为辅助的。见下面的示例: 多个 %d 占位符允许你在文件夹中去管理归档文件,这个跟轮转周期不同。如下所示:通过年月来管理日志文件夹,但是轮转周期是在每天晚上零点。 /var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log TimeZone 在某些情况下,你可能想要根据时区而不是主机的时钟来轮转日志。你可以通过如下方式来指定一个时区,例如:aFloder/test.%d{yyyy-MM-dd-HH, UTC}.log 如果指定的 timezone 不能被识别或者拼写错误,将会根据 TimeZone.getTimeZone(String) 方法指定为 GMT。 |
maxHistory | int | 这个可选的属性用来控制最多保留多少数量的归档文件,将会异步删除旧的文件。比如,你指定按月轮转,指定 maxHistory = 6,那么 6 个月内的归档文件将会保留在文件夹内,大于 6 个月的将会被删除。注意:当旧的归档文件被移除时,当初用来保存这些日志归档文件的文件夹也会在适当的时候被移除。 |
totalSizeCap | int | 这个可选属性用来控制所有归档文件总的大小。当达到这个大小后,旧的归档文件将会被异步的删除。使用这个属性时还需要设置 maxHistory 属性。而且,maxHistory 将会被作为第一条件,该属性作为第二条件。 |
cleanHistoryOnStart | boolean | 如果设置为 true,那么在 appender 启动的时候,归档文件将会被删除。默认的值为 false。 归档文件的删除通常在轮转期间执行。但是,有些应用的存活时间可能等不到轮转触发。对于这种短期应用,可以通过设置该属性为 true,在 appender 启动的时候执行删除操作。 |
详见:http://www.logback.cn/04%E7%AC%AC%E5%9B%9B%E7%AB%A0Appenders.html
下面是 RollingFileAppender
与 TimeBaseRollingPolicy
结合使用的例子:
Example: logback-RollingTimeBased.xml
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天轮转 -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 保存 30 天的历史记录,最大大小为 30GB -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
下面是在 prudent
模式下(严格模式)RollingFileAppender
与 TimeBasedRollingPolicy
的结合使用的例子:
Example: logback-PrudentTimeBasedRolling.xml
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 支持多个 JVM 同时写一个文件 -->
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
基于大小以及时间的轮转策略
有时你希望按时轮转,但同时又想限制每个日志文件的大小。特别是如果后期处理工具需要对日志进行大小限制。为了满足这个需求,logback 配备了 SizeAndTimeBasedRollingPolicy。
下面的示例展示了基于时间及大小的配置:
<configuration debug="true">
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 按天轮转 -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
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 格式。 |
由于窗口固定算法需要跟窗口大小一样的的重命名次数,因此强烈不推荐太大的窗口大小。当用户指定一个较大值时,当前的实现会将窗口大小自动减少为 20。
用例
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
触发策略简介
TriggeringPolicy
的实现用于通知 RollingFileAppender
何时轮转。
TriggeringPolicy
接口仅仅只包含了一个方法。
package ch.qos.logback.core.rolling;
import java.io.File;
import ch.qos.logback.core.spi.LifeCycle;
public interface TriggeringPolicy<E> extends LifeCycle {
public boolean isTriggeringEvent(final File activeFile, final <E> event);
}
isTriggeringEvent()
方法接收当前活动的文件以及当前的日志事件作为参数。基于这些参数,通过具体的实现来决定轮转是不是应该发生。
TimeBasedRollingPolicy
是使用最广泛的触发策略。也可以用作轮转策略来使用。
SizeBasedTriggeringPolicy
SizeBasedTriggeringPolicy
观察当前活动文件的大小,如果已经大于了指定的值,它会给 RollingFileAppender
发一个信号触发对当前活动文件的轮转。
SizeBasedTriggeringPolicy
只接收 maxFileSize
这一个参数,它的默认值是 10 MB。
maxFileSize
可以为字节,千字节,兆字节,千兆字节,通过在数值后面指定一个后缀 KB,MB 或者 GB。例如,5000000,5000KB,5MB 以及 2GB 都是有效的,前三个是一样的。
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>test.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>