一、什么是Appender?
Logback会把书写日志事件的任务委托给叫做appender的组件,appenders必须实现ch.qos.logback.core.Appender接口,该接口方法如下:
package ch.qos.logback.core; import ch.qos.logback.core.spi.ContextAware; import ch.qos.logback.core.spi.FilterAttachable; import ch.qos.logback.core.spi.LifeCycle; public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable { public String getName(); public void setName(String name); void doAppend(E event); }
Appender接口中的方法大多是getter或setter方法,而doAppend()方法例外,该方法携带E类型的实例作为唯一参数。E的实际类型取决于logback组件,在logback-classic里,E的类型为ILoggingEvent,而在logback-access组件里,E的类型为AccessEvent。doAppend()方法负责以合适的方式输出日志事件到输出设备。
Appender接口继承自FilterAttachable接口,因此可以绑定一个或多个filters。Appenders负责输出日志事件,但它可能会把实际日志格式化事件委托给Layout或者Encoder对象。而有些Appenders有内置或者固定的事件格式,因此不需要配置layout或者encoder。
Appender相关类图如下:
二、Appender分类
1、ConsoleAppender
见名知意,日志信息输出到控制台,也就是通过System.out或者System.err输出,前者是默认值。
属性名 | 类型 | 备注 |
encoder | Encoder | 编码器。 |
target | String |
有效值为System.out或者System.err,默认为System.out。 |
withJansi | boolean |
默认为false,设为true激活Jansi库,该库提供了windows机器上ANSI颜色编码支持,用不上。 |
示例:
<configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="STDOUT" /> </root> </configuration>
2、FileAppender
OutputStreamAppender的子类,输出日志信息到文件中,目标文件通过File选项指定。
属性名 | 类型 | 备注 |
append | boolean |
是否追加到指定文件。 |
encoder | Encoder | 编码器。 |
file | String |
写入日志信息的文件名,如果文件不存在,自动创建。 |
prudent | boolean |
谨慎模式写入,默认为false。当多个JVM中的Appender实例写入相同文件时,谨慎模式下会串行I/O操作。 |
示例:
<configuration> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>testFile.log</file> <append>true</append> <!-- set immediateFlush to false for much higher logging throughput --> <immediateFlush>true</immediateFlush> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="FILE" /> </root> </configuration>
2.1 日志文件唯一命名(通过timestamp)
<configuration> <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under the key "bySecond" into the logger context. This value will be available to all subsequent configuration elements. --> <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" timeReference="contextBirth"/> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <!-- use the previously created timestamp to create a uniquely named log file --> <file>log-${bySecond}.txt</file> <encoder> <pattern>%logger{35} - %msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="FILE" /> </root> </configuration>
<timestamp>元素两个必选属性为key和datePattern,可选属性为timeReference,key指定名字,dataPattern指定日期转换格式,timeReference指定引用的时间戳。
3、RollingFileAppender
RollingFileAppender继承自FileAppender,用于翻滚日志文件。例如,写入日志信息到名为log.txt的文件,由于超出指定的文件大小限制,日志输出到另一个文件。
属性名 | 类型 | 备注 |
file | String |
参考FileAppender。 |
append | boolean |
参考FileAppender。 |
encoder | Encoder | 编码器。 |
rollingPolicy | RollingPolicy |
滚动策略。 |
triggeringPolicy | TriggeringPolicy |
触发策略。 |
prudent | boolean |
参考FileAppender。 |
3.1 滚动策略
滚动策略负责日志文件移动和重命名相关滚动步骤,该接口api如下:
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); }
3.1.1 TimeBasedRollingPolicy(基于时间的滚动策略)
基于时间的滚动策略是最长使用的滚动策略,可以通过天或者月份制定何时滚动。
下面是一些fileNamePattern的示例:
TimeBasedRollingPolicy支持归档日志文件自动压缩,如果fileNamePattern的值以.gz或者.zip结尾则可利用该特性。
示例1 (滚动策略为TimeBasedRollingPolicy的RollingFileAppender):
<configuration> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logFile.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- daily rollover --> <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- keep 30 days' worth of history capped at 3GB total size --> <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>
示例2 (谨慎模式):
<configuration> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- Support multiple-JVM writing to the same log file --> <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>
3.1.2 Size and time based rolling policy(基于文件大小和时间的滚动策略)
通过这种策略可以按日期来归档日志文件,同时也可以限制每个日志文件的大小,示例如下:
<configuration> <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>mylog.txt</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- rollover daily --> <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern> <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB --> <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>
注意:%i转换符和%d在这里是必须的,当前时间周期内如果日志文件大小达到了maxFileSize,则会进行归档,文件名以从0开始的递增索引命名,%i表示从0开始递增索引。例如:mylog-2019-05-05.0.txt
3.1.3 FixedWindowRollingPolicy(固定窗口的滚动策略)
滚动时会根据固定窗口算法重命名文件,下面是FixedWindowRollingPolicy的可用属性:
假设minIndex被设为1,maxIndex被设为3,fileNamePatter被设为foo%i.log,file属性被设为foo.log,具体示例如下:
配置如下:
<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>
三、TriggerPolicy(触发策略)
TriggerPolicy实现负责指导RollingFileAppender什么时候回滚,该接口如下:
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); }
1、SizeBasedTriggeringPolicy
SizeBasedTriggeringPolicy会观察当前日志文件的大小,如果增长到指定值,会通知RollingFileAppender触发滚动。SizeBasedTriggeringPolicy只接受一个参数,也就是maxFileSize,默认值为10MB。maxFileSize选项的值可以是bytes、kilobytes、megabytes、gigabytes。例如:5000000、5000KB、5MB、2GB,前面三个等价。
下面是RollingFileAppender结合SizeBasedTriggeringPolicy配置示例:
<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>
结语:其它的appender还有SocketAppender、SSLSocketAppender、SMTPAppender等,具体参考:Chapter 4: Appenders