springboot项目中logback日志几种配置方式
logback简介
Logback由log4j的创始人CekiGülcü设计,是流行的日志框架log4j项目的后续版本。logback建立在CekiGülcü长久的工业级项目的设计经验之上,
其资源占用及运行效率,要低于现存的所有日志框架,并提供了一些在其它日志系统中不存在的功能。
springboot当前默认的日志框架是logback,所以使用起来也是非常方便。
Logback被分为3个组件:
- logback-core
- logback-classic
- logback-access
其中logback-core提供了LogBack的核心功能,是另外两个组件的基础。
logback-classic则实现了Slf4j的API,所以当想配合Slf4j使用时,需要将logback-classic加入classpath。logback-access是为了集成Servlet环境而准备的,可提供HTTP-access的日志接口。
配置文件详解
一个完整的logback配置文件由三部分组成,如下图所示:
- appender 负责写日志的组件,对日志的输出格式以及滚动规则进行配置
- logger 用来设置某一个包或者具体的某一个类的日志打印级别、以及指定appender
- root 根logger,可以包含零个或多个appender-ref元素,表示这个appender将会添加到这个logger
配置文件结构如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 定义变量值 -->
<property name="contextName" value="logback-test" />
<property name="logDir" value="./logs" />
<!--设置应用上下文名称-->
<contextName>${contextName}</contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 控制台 appender -->
</appender>
<appender name="ERROR">
<!-- 出错日志 appender -->
</appender>
<appender name="ACCESS">
<!-- 访问日志 appender -->
</appender>
<appender name="INFO">
<!-- info日志 appender -->
</appender>
<logger name="com.haiyoung" additivity="false">
<!--日志打印的包的范围,日志打印级别以及指定appender -->
<!--当additivity属性设置为false时,此loggerd的打印信息不向上级传递,日志只在logger内配置的appender输出;additivity属性默认为true,表示日志信息向上级root传递,日志不止会在自己的appender里输出,还会在root的appender里输出-->
</logger>
<root level="info">
<!--根logger,一个特殊的logger,当其它logger的additivity属性为true时,将向root传递,子logger的日志向root传递时,会忽略root的日志级别-->
</root>
</configuration>
常用日志输出格式
<!--
日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:日志级别从左显示5个字符宽度
%logger 表示logger名字,可限制长度。 %msg:日志消息,%n是换行符
-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
按时间回滚
- 日志按照时间滚动,按照fileNamePattern节点配置的最小时间单位(此处按分钟切割)滚动切割日志
- 保留三十个时间周期内的日志
配置文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="logDir" value="./logs" />
<!-- 控制台 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- 出错日志 appender -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}-error.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 访问日志 appender -->
<appender name="ACCESS" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}-access.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- info日志 appender -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}-info.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="com.haiyoung.lbtest" additivity="false">
<level value="DEBUG" />
<appender-ref ref="STDOUT"/>
<appender-ref ref="ERROR"/>
<appender-ref ref="ACCESS"/>
<appender-ref ref="INFO" />
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
按时间和大小回滚
- 日志按照时间和大小滚动,按照fileNamePattern节点配置的最小时间单位(此处按分钟切割)滚动切割日志
- 当日志大于10MB时,切割出新的日志文件,以数字 i 区分日志文件
- 保留三十个时间周期内的日志
配置文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="logDir" value="./logs" />
<!-- 控制台 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- 出错日志 appender -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}.%i-error.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 访问日志 appender -->
<appender name="ACCESS" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}.%i-access.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- info日志 appender -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}.%i-info.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="com.haiyoung.lbtest" additivity="false">
<level value="DEBUG" />
<appender-ref ref="STDOUT"/>
<appender-ref ref="ERROR"/>
<appender-ref ref="ACCESS"/>
<appender-ref ref="INFO" />
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
自定义回滚周期
logback默认配置都是按照每天,每小时,每分钟这样来滚动切割日志的,如果想自定义滚动周期,则需要
实现DefaultTimeBasedFileNamingAndTriggeringPolicy,重写computeNextCheck方法
@NoAutoStart
public class SelfDefineTimeBasedFileNamingAndTriggeringPolicy extends DefaultTimeBasedFileNamingAndTriggeringPolicy {
private Integer multiple = 1;
@Override
protected void computeNextCheck() {
nextCheck = rc.getEndOfNextNthPeriod(dateInCurrentPeriod, multiple).getTime();
}
public Integer getMultiple() {
return multiple;
}
public void setMultiple(Integer multiple) {
if (multiple > 1) {
this.multiple = multiple;
}
}
}
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="logDir" value="./logs" />
<!-- 控制台 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- 出错日志 appender -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}-error.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="com.haiyoung.lbtest.SelfDefineTimeBasedFileNamingAndTriggeringPolicy">>
<multiple>3</multiple>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 访问日志 appender -->
<appender name="ACCESS" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}-access.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="com.haiyoung.lbtest.SelfDefineTimeBasedFileNamingAndTriggeringPolicy">>
<multiple>3</multiple>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- info日志 appender -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd_HH-mm}-info.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="com.haiyoung.lbtest.SelfDefineTimeBasedFileNamingAndTriggeringPolicy">>
<multiple>3</multiple>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="com.haiyoung.lbtest" additivity="false">
<level value="DEBUG" />
<appender-ref ref="STDOUT"/>
<appender-ref ref="ERROR"/>
<appender-ref ref="ACCESS"/>
<appender-ref ref="INFO" />
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
注意事项
当日志滚动周期内,没有日志生成时,是不会触发日志切割生成新的日志文件的;在学习logback配置时,容易造成困惑,从而怀疑配置问题,其实配置是没有问题的。