既然使用Logback,应该对它多些了解(二)
上一篇:https://www.jianshu.com/p/824d5396d9ec
1. 变量作用范围(logback scopes)
在Logback中,变量有三种不同的scope:local scope ,context scope,system scope。
在变量替换的时候,首先从local scope中找,然后是context scope,然后是system properties中找,最后是操作系统环境变量中找。
可以在<property> <define> <insertFromJNDI>元素中使用scope属性,它的属性值可以是:local,context,system。如果不指定,默认是local。
<configuration>
<property scope="context" name="nodeId" value="firstNode" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>/opt/${nodeId}/myApp.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
2. 变量之间可以引用
USER_HOME=/home/sebastien
fileName=myApp.log
destination=${USER_HOME}/${fileName}
3. 条件判断启用不同的logback配置
两种不同的格式:
<!-- if-then form -->
<if condition="some conditional expression">
<then>
...
</then>
</if>
<!-- if-then-else form -->
<if condition="some conditional expression">
<then>
...
</then>
<else>
...
</else>
</if>
4. 引用公共配置
有时候,在多个项目开发中,日志的配置有一部分是统一的配置,可以把这些公共的配置提取到一个公共的配置文件中,在主配置文件中引用这个公共配置的文件。
比如一个主配置文件为:
<configuration>
<include file="src/main/java/chapters/configuration/includedConfig.xml"/>
<root level="DEBUG">
<appender-ref ref="includedConsole" />
</root>
</configuration>
公共配置文件为:
<included>
<appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>"%d - %m%n"</pattern>
</encoder>
</appender>
</included>
- 注意,这里的<included>标记是不能少的。
引用文件的方式有三种:
- 从文件路径中引用
<include file="src/main/java/chapters/configuration/includedConfig.xml"/>
- 从classpath中引用
<include resource="includedConfig.xml"/>
- 从URL中引用
<include url="http://some.host.com/includedConfig.xml"/>
如果引用的文件是可有可无的,则可以把它定义为可选择的:
<include optional="true" ..../>
5. 缓存日志输出,提高日志吞吐量
如果日志允许丢失,把Appender中的immediateFlush设置为false,可以明显提高日志的吞吐量。
6. 每次启动都创建一个日志文件
在一些不是常驻内存的应用中,每次启动应用都创建一个新的日志文件是非常合适的。可以使用<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"/>
<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>
datePattern配置的值只要可以被SimpleDateFormat转化就可以。
7. RollingFileAppender
RollingFileAppender有两个重要的组件:RollingPolicy 和 TriggeringPolicy。前者决定如何滚动日志文件,需要一种策略,后者决定何时开始滚动日志文件,需要的是一个触发点。
7.1 TimeBasedRollingPolicy
这是一个常见的日志滚动策略,它基于时间滚动,比如每天生成一个日志文件,或每月生成一个日志文件。它同时实现了RollingPolicy 和 TriggeringPolicy接口。在TimeBasedRollingPolicy可以配置下面这些属性:
- fileNamePattern 日志文件名样式
这是一个必须配置的属性。它定义每次滚动日志文件时,日志文件名称的生成方式。它一般由占位符%d和日志名组成。%d可以指定日期和时间,由java.text.SimpleDateFormat进行格式化。如果只有%d,它默认使用yyyy-MM-dd的日期格式。在RollingFileAppender中,<file>标签是可以省略的,如果设置了file的值,当前的日志都会输入到这个file配置的文件中。它可以将当前输出的日志文件和滚动归档的日志文件分离。如果不配置file标签,则随着时间的变化,当前输出的日志会创建新的日志文件。
如果在一个fileNamePattern标签下用到多个%d,刚只能有一个是做为滚动日志文件的日期判断。其它的都只能是辅助的。例如,每天生成一个日志文件,每个月的日志文件放在一起:
/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log
在配置中,也可以指定时区,比如:
Folder/test.%d{yyyy-MM-dd-HH, UTC}.log
如果指定的时区不存在,或没有指定,默认使用GMT时区。
-
maxHistory 保留的历史日志文件最大数量
比如你配置的是每天生成一个日志文件,maxHistory配置的是6,那么就会只保留6个日志文件,即六天的日志。如果是每月生成一个日志文件,则是保留6个月的日志文件,因为一个日志文件记录一个月的日志。当日志文件超过这个数量时,最早的日志文件会被异步删除。 -
totalSizeCap
这个属性限制保留的日志总大小,如果日志文件总的大小超过这个限制,就会异步删除最早的日志文件。这个属性需要配合maxHistory一起使用,logback会首先判断maxHistory,然后再计算日志总量是否超过这个限制。 -
cleanHistoryOnStart
这个属性默认是false,如果设置为true,则应用启动的时候都会删除以前旧的日志。
在开发环境下可以配置为true。
下面是一些常见的格式配置:
日志文件样式配置 | 例子说明 |
---|---|
/log/foo.%d | 1. 当不设置<file>标签时,如果现在的日期是2020-05-23,当前的日志会输出到/log/foo.2020-05-20的日志文件中,过了24点之后,会输出到/log/foo.2020-05-20的日志文件中。2. 如果设置file标签为:<file>/log/foo.log</file>,当前日志会输出到/log/foo.log文件中,过了24点之后,foo.log会重命名为/log/foo.2020-05-23,然后重新创建一个/log/foo.log文件,当前日志会输出到新的文件中。 |
/log/%d{yyyy/MM}/foo.txt | 每月生成一个新的日志文件,设置与不设置file和上面的一样。 |
/log/foo.%d{yyyy-ww}.log | 每周生成一个日志文件。 |
/log/foo%d{yyyy-MM-dd_HH}.log | 每小时生成一个日志文件 |
/log/foo%d{yyyy-MM-dd_HH-mm}.log | 每分钟生成一个日志文件 |
/log/%d{yyyy-MM,aux}/%d.log | 每天生成一个日志文件,旧的文件归档到年月的文件夹里面,比如2020-05。 |
-
如果配置的文件路径不存在,logback会自动创建。
-
TimeBasedRollingPolicy 支持自动压缩,如果配置的fileNamePattern以.gz或.zip结尾,就会自动压缩。
例如 :/log/foo.%d.zip
下面是一个配置示例:
<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>
如果想支持多个JVM进程向同一个日志文件中写日志,设置prudent参数为true:
<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>
7.2 Size and time based rolling policy
有时候希望日志既按天分割,又按大小分割,比如当日志文件不足1G的时候,每天创建一个新的日志文件,同一天内,如果日志文件大小超过1G的时候,也创建一个新的日志文件。就可以使用这个SizeAndTimeBaseRollingPolicy。
<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>
- 注意,这里面的配置中,%d和%i都是必不可少的。
7.3 SizeBasedTriggeringPolicy
这个触发策略只有一个参数,maxFileZie,默认是10MB,当文件达到配置的大小时,就分触发日志分割,创建新的日志文件。它支持的单位有:KB,MB,GB。
在使用这个策略时,fileNamePattern必须有%i。
![](https://img.haomeiwen.com/i3793531/38abdf16d393adfc.png)