logback实战详解fileNamePattern配置问题%d多级日期文件夹
·
为什么写这个呢?
因为我遇到了一个问题多个%d的问题,日志文件要么不按照日期文件目录划分,要么日志文件名字不变,结果处理了好久
原来是因为logback只会根据第一个%d去划分,所以需要忽略前面的%d,添加一个
,aux很关键,这样他就会忽略前面的按照后面的来滚动划分,具体看实战案例
以下是 基于Logback 1.5.12 的
logback.xml完整配置详解,涵盖核心组件、常用场景和该版本的注意事项。
实战案例
及其简略的案例,可以生产直接使用
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<contextName>com.cmit</contextName>
<property name="pattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L -[%X{TRACE_ID}] - %msg %n"/>
<property name="LOG_HOME" value="logs"/>
<property name="PROJECT_NAME" value="project-name"/>
<property name="MAX_FILE_SIZE" value="10MB" />
<property name="MAX_HISTORY" value="200" />
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!-- 文件输出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${PROJECT_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/%d{yyyy-MM,aux}/${PROJECT_NAME}/${PROJECT_NAME}-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
<maxHistory>${MAX_HISTORY}</maxHistory>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>${pattern}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
文件基础结构
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 属性定义 -->
<property name="LOG_HOME" value="./logs"/>
<property name="APP_NAME" value="myapp"/>
<!-- Appender 定义 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
...
</appender>
<!-- Logger 定义 -->
<logger name="com.example" level="DEBUG"/>
<!-- 根 Logger -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
核心组件详解
<configuration> 根标签属性
| 属性 | 说明 | 示例 |
|---|---|---|
scan |
是否自动扫描配置文件变更 | scan="true" |
scanPeriod |
扫描间隔,默认 60 秒 | scanPeriod="30 seconds" |
debug |
是否打印 logback 内部状态 | debug="false" |
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<property> 属性定义
<!-- 直接定义 -->
<property name="LOG_PATH" value="/var/log/myapp"/>
<!-- 引用系统属性 -->
<property name="LOG_PATH" value="${user.home}/logs"/>
<!-- 默认值语法(属性不存在时使用默认值) -->
<property name="LOG_LEVEL" value="${LOG_LEVEL:-INFO}"/>
Appender 详解
ConsoleAppender(控制台输出)
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志立即刷新,性能会略降但确保不丢失 -->
<immediateFlush>true</immediateFlush>
<!-- 编码器 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 过滤器:只输出 INFO 及以上 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
常用 Pattern 符号:
| 符号 | 含义 |
|---|---|
%d{...} |
日期时间 |
%thread |
线程名 |
%-5level |
日志级别,左对齐占5字符 |
%logger{36} |
Logger 名,最长36字符 |
%msg / %m |
日志消息 |
%n |
换行 |
%line / %L |
输出代码行号(性能开销大,生产慎用) |
%M |
方法名(性能开销大) |
FileAppender(单文件输出)
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOG_HOME}/app.log</file>
<append>true</append> <!-- true=追加,false=覆盖 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %level %logger - %msg%n</pattern>
</encoder>
</appender>
RollingFileAppender(滚动日志)⭐最常用
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当前正在写入的文件 -->
<file>${LOG_HOME}/app.log</file>
<!-- 滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档文件名格式,%d 触发按天滚动 -->
<fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 保留最近 30 天的归档日志 -->
<maxHistory>30</maxHistory>
<!-- 启动时清理超期日志 -->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
<!-- 单个归档文件最大 100MB(TimeBasedRollingPolicy 不支持,需用 SizeAndTimeBasedRollingPolicy) -->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
SizeAndTimeBasedRollingPolicy(按时间和大小双重滚动)⭐推荐
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- %i 是序号,同一天内超过大小则递增 -->
<fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 单个文件最大 100MB -->
<maxFileSize>100MB</maxFileSize>
<!-- 保留 30 天的日志 -->
<maxHistory>30</maxHistory>
<!-- 所有日志总大小上限(防止磁盘满) -->
<totalSizeCap>10GB</totalSizeCap>
<!-- 启动时清理 -->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
注意:
SizeAndTimeBasedRollingPolicy是TimeBasedRollingPolicy的子类,功能更强大,生产环境建议直接使用这个。
Logger 层级配置
<!-- 设置特定包的日志级别 -->
<logger name="com.example.dao" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING_FILE"/>
</logger>
<!-- Spring 框架日志 -->
<logger name="org.springframework" level="WARN"/>
<logger name="org.springframework.jdbc" level="DEBUG"/>
<!-- MyBatis 日志 -->
<logger name="com.ibatis" level="DEBUG"/>
<logger name="java.sql" level="DEBUG"/>
<!-- 根 Logger,所有日志的默认配置 -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING_FILE"/>
</root>
additivity="false" 的重要性:
-
true(默认):日志会同时输出到当前 logger 的 appender 和父 logger(root)的 appender,导致重复打印 -
false:只输出到当前 logger 配置的 appender
过滤器(Filter)
<!-- 级别过滤器:精确匹配级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 阈值过滤器:该级别及以上通过 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
高级配置
异步日志(AsyncAppender)
<!-- 先定义同步 appender -->
<appender name="FILE_SYNC" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 包装为异步 appender -->
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 队列大小,默认 256 -->
<queueSize>512</queueSize>
<!-- 队列满时的策略:false=丢弃,true=阻塞 -->
<discardingThreshold>0</discardingThreshold>
<!-- 不丢失日志事件 -->
<neverBlock>false</neverBlock>
<!-- 引用同步 appender -->
<appender-ref ref="FILE_SYNC"/>
</appender>
<root level="INFO">
<appender-ref ref="ASYNC_FILE"/>
</root>
按日志级别分离文件
<!-- INFO 及以上 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- 仅 ERROR -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %logger{36} - %msg%n%ex{full}</pattern>
</encoder>
</appender>
彩色控制台输出(Logback 1.5.x 支持)
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
</encoder>
</appender>
高亮颜色:
-
%highlight():根据级别自动着色(ERROR=红,WARN=黄,INFO=绿等) -
%cyan()、%magenta()、%yellow()等
Logback 1.5.x 版本注意事项
安全性增强
-
1.5.x 修复了 CVE-2023-6378(序列化漏洞)等安全问题
-
建议确保
logback.xml中不要配置从 JNDI / 远程加载配置,避免被利用
maxHistory 和 cleanHistoryOnStart 的行为
-
maxHistory按归档文件的时间戳计算,不是按文件创建时间 -
cleanHistoryOnStart=true只在应用启动时执行一次清理 -
如果应用长期不重启,超期文件不会被自动清理(需依赖定时任务或确保会重启)
推荐的最小完整配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="LOG_HOME" value="${user.home}/logs/myapp"/>
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<!-- 控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 文件滚动 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 第三方框架降噪 -->
<logger name="org.springframework" level="WARN"/>
<logger name="org.apache.http" level="WARN"/>
<logger name="com.zaxxer.hikari" level="INFO"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
更多推荐
所有评论(0)