<?xml version="1.0" encoding="UTF-8"?>
<!-- 每隔30s自动检查配置文件是否改变,改变的话重新加载配置 -->
<configuration scan="true" scanPeriod="5 seconds">
<!-- 设置日志输出根目录为用户主目录下的logs目录,没有会新建 -->
<property name="log.dir" value="${user.home}/logs"/>
<!-- 使用springboot默认配置,其中有CONSOLE_LOG_PATTERN和FILE_LOG_PATTERN的配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!-- 增加一个jvm关闭时的hook,释放logback的线程和资源,jvm关闭时延迟3s关闭logback context -->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook">
<delay>3000</delay>
</shutdownHook>
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>UTF-8</charset>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- info日志中记录日记级别大于等于info级别的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<file>${log.dir}/info.log</file>
<encoder>
<charset>UTF-8</charset>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<maxFileSize>5GB</maxFileSize>
<totalSizeCap>30GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<appender name="async_infoAppender" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="infoAppender"/>
<!-- 队列大小 -->
<queueSize>2048</queueSize>
<!-- 队列满了也不丢弃日志,会阻塞住。如果设置了neverBlock为true(默认false),队列满会丢弃日志,不阻塞 -->
<discardingThreshold>0</discardingThreshold>
<!-- logback context关闭后,处理队列中未写入日志的最大时间,到时间还没有写入磁盘的就丢弃 -->
<maxFlushTime>2500</maxFlushTime>
</appender>
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<file>${log.dir}/error.log</file>
<encoder>
<charset>UTF-8</charset>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<maxFileSize>5GB</maxFileSize>
<totalSizeCap>30GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<appender name="async_errorAppender" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="errorAppender"/>
<discardingThreshold>0</discardingThreshold>
<maxFlushTime>2500</maxFlushTime>
<queueSize>2048</queueSize>
</appender>
<root level="INFO">
<!-- 只在spring.profiles.active为local时向控制台打印 -->
<springProfile name="local">
<appender-ref ref="consoleAppender"/>
</springProfile>
<appender-ref ref="async_infoAppender"/>
<appender-ref ref="async_errorAppender"/>
</root>
</configuration>
- 使用异步appender,运行机制主要看AsyncAppenderBase,默认配置如下

- 可以看出为什么官方文档说:
when the blocking queue has 20% capacity remaining, it will drop events of level TRACE, DEBUG and INFO, keeping only events of level WARN and ERROR
;discardingThreshold 未指定时用的是队列大小/5

- neverBlock的作用,异步appender中的queue在上图可以看到是ArrayBlockingQueue,neverBlock为true时,调用的offer方法,队列满直接丢弃不阻塞

- 使用logback严格控制日志的大小可以如下配置和
<appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/application.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<charset>UTF-8</charset>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${LOG_PATH}/application.%i.log.gz</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>1GB</maxFileSize>
</triggeringPolicy>
</appender>