1、说明
logback日志框架由三部分组成:logback-core
、logback-access
、logback-classic
。使用起来也很方便需要在项目目录下增加logback.xml文件。在springboot项目,框架已经集成了logback(默认的日志框架),只需要在项目resource
下配置logback.xml文件
或者logback-spring.xml
文件。这里主要记录的是logback配置文件的内容部分。
2、logback. xml文件
在学习logback时,我们需要了解设计者的思维方式。我们才能更好的配置出我们需要的日志策略及性能。
2.1 设计思路
(1)控制台日志和写入文件日志分开
日志本身是可追加写入的,定义为追加器:appender
,控制台和写入文件日志分别有ConsleAppdender
和 FileAppender
两个追加器处理。
(2)日志打印的内容可以控制参数格式
打印出的日志一定是规整的,便于开发跟踪问题。例如:问题发生的时间,由于大部分程序都是多线程运行的,则需要知道每个业务请求的线程号,出问题的使用到的类名等等.
<encoder>
<pattern><![CDATA[%n[%d{yyyy-MM-dd HH:mm:ss.SSS}] [level: %p] [Thread: %t] [ Class:%c >> Method: %M:%L ]%n%p:%m%n]]></pattern>
</encoder>
(3)写入文件中的日志不宜过大同时考虑时间跨天问题
考虑到将文件分开(可卷起Rolling
),则使用升级的追加器RollingFileAppender
,同时分开规则(Policy
)考虑到跨天跨时间 。则在追加器中定义拆分规则:SizeAndTimeBasedRollingPolicy
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.base}/%d{yyyyMMdd}/${app.name}_%d{yyyyMMdd}_%i.log.gz</fileNamePattern>
<!--文件大小-->
<maxFileSize>2GB</maxFileSize>
<!--历史个数-->
<maxHistory>180</maxHistory>
</rollingPolicy>
(4)日志应该可以灵活指定输出级别
针对“ com.sports ”包下的日志,控制台和日志文件都使用debug级别。
<logger name="com.sports" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG_FILE"/>
<!--<appender-ref ref="myAppender"/>-->
</logger>
(5)必须对主体日志指定输出级别
虽然我们会对不同的包或者框架下日志设置输出级别,但不可缺少主体日志输出级别:root
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG_FILE"/>
<!--<appender-ref ref="mqAppender"/>-->
</root>
(6)日志可以异步写入
通常日志是和业务应用公用同一个线程,写系统日志会有IO
开销,会损耗性能,我们应该可以异步写日志
<!-- 异步输出 -->
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="INFO-LOG"/>
</appender>
2.2 文件样例
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern><![CDATA[%n[%d{yyyy-MM-dd HH:mm:ss.SSS}] [level: %p] [Thread: %t] [ Class:%c >> Method: %M:%L ]%n%p:%m%n]]></pattern>
</encoder>
</appender>
<appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern><![CDATA[%n[%d{yyyy-MM-dd HH:mm:ss.SSS}] [level: %p] [Thread: %t] [ Class:%c >> Method: %M:%L ]%n%p:%m%n]]></pattern>
</encoder>
<file>logs/sports-web.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/sports-web.-%d{yyyyMMdd}.%i.log</fileNamePattern>
<!-- 每天一个日志文件,当天的日志文件超过10MB时,生成新的日志文件,当天的日志文件数量超过totalSizeCap/maxFileSize,日志文件就会被回滚覆盖。 -->
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
</appender>
<logger name="com.sports" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG_FILE"/>
<!--<appender-ref ref="myAppender"/>-->
</logger>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG_FILE"/>
<!--<appender-ref ref="mqAppender"/>-->
</root>
</configuration>
3、日志格式pattern部分
logback框架日志格式通过PatternLayout
方式配置,样例:
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder
encoder作用:①把日志信息转换成字节数组;②把字节数组写入到输出流。
PatternLayoutEncoder
是唯一有用的且默认的encoder
,encoder
下只有一个pattern
节点。
(1)% + “转换符号”输出信息
%t
: t表示线程的转换符,打印控制台" [Thread: restartedMain]"
pattern中的转换符列表
转换符 | 说明 | 使用方式 | 备注 |
---|---|---|---|
m / msg / message | 应用程序输出信息 | %msg | 主要内容信息 |
M / method | 输出执行日志请求的方法名。 | %M | 尽量避免使用,除非执行速度不造成任何问题 |
p / le / level | 日志等级 | %p | |
L / line | 行号 | %line | 尽量避免使用,除非执行速度不造成任何问题 |
(2)格式修饰符
与转换符共同使用,可选的格式修饰符位于“%”和转换符之间
左对齐 修饰符 :符号是减号“-”;接着是可选的最小宽度 修饰符,用十进制数表示
(3)使用slf4j
中的MDC
新增线程参数
“%X
”用于输出和当前线程相关联的MDC
(嵌套诊断环境),格式 %X{xxx},使用org.slf4j.MDC
添加key/value
即可增加新值,
<encoder>
<pattern>%d{yyyy-MM-dd hh:mm:ss} [%thread] [traceId = %X{traceId}] [%logger{32}] - %msg%n</pattern>
</encoder>
其中tracId是在MDC中设置进当前线程中的参数,记得在线程运行完时清除clear
掉。
@Before(value = "pointCut()")
public void before(JoinPoint joinPoint){
// 省略代码...
MDC.put("traceId", UUID.randomUUID().toString());
}
- 结束清除
@AfterReturning(value = "pointCut()", returning = "val")
public void afterReturning(JoinPoint joinPoint, Object val) {
// 省略代码...
MDC.clear();
}
- 各个参数说明
示例 | 说明 |
---|---|
%X | 输出所有值 |
%X{testKey} | 输出testKey所对应的value,且无默认值 |
%X{testKey:-} | 输出testKey所对应的value,默认为空 |
%X{testKey:-aaa} | 输出testKey所对应的value,默认为aaa |
网友评论