Log4j2 配置详解:从基础到实战的完整指南
Log4j2 作为主流的日志实现框架,以其高性能、灵活的配置和丰富的功能(如异步日志、动态配置)被广泛应用。其配置文件通过 XML、JSON 或 YAML 定义日志的输出目的地、格式、滚动策略等。本文基于 XML 配置格式,详细解析 Log4j2 的配置结构与核心功能。
Log4j2 配置文件基本结构
Log4j2 配置文件的根元素为<Configuration>,包含两大核心子元素:<Appenders>(日志输出目的地)和<Loggers>(日志器,控制日志流向)。基本结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30"> <Appenders> <Appender name="控制台" ...> <Filters>...</Filters> <PatternLayout .../> <Policies>...</Policies> <DefaultRolloverStrategy .../> </Appender> </Appenders>
<Loggers> <Logger name="com.example" level="INFO" additivity="false"> <AppenderRef ref="控制台"/> </Logger> <Root level="INFO"> <AppenderRef ref="控制台"/> </Root> </Loggers> </Configuration>
|
Appenders:日志输出目的地
<Appenders>定义日志的输出位置(如控制台、文件),每个<Appender>需指定name(唯一标识)和具体类型(如Console、File、RollingFile)。
1. Console:输出到控制台
最基础的 Appender,用于将日志输出到控制台(SYSTEM_OUT或SYSTEM_ERR)。
1 2 3 4 5 6 7
| <Console name="stdout" target="SYSTEM_OUT"> <PatternLayout charset="UTF-8" <!-- 字符编码 --> pattern="[%-5p %d{yyyy-MM-dd HH:mm:ss.SSS}] %l [%m]%n" /> </Console>
|
pattern常用占位符(后续 Layout 通用):
%d{格式}:日志时间(如%d{yyyy-MM-dd HH:mm:ss.SSS});
%p:日志级别(如 INFO、WARN,%-5p表示左对齐占 5 位);
%l:日志发生位置(类名、方法名、行号,如com.example.Test.main(Test.java:10));
%m:日志消息;
%n:换行符;
%t:线程名;
%X{key}:MDC 中的键值(如%X{traceId}输出追踪 ID)。
2. File:输出到固定文件
将日志输出到指定文件,不支持日志滚动(文件大小会无限增长,适合临时调试)。
1 2 3 4 5 6 7
| <File name="fileLog" fileName="logs/app.log" <!-- 文件路径(相对路径基于项目根目录,绝对路径如D:/logs/app.log) --> append="true" > <PatternLayout charset="UTF-8" pattern="[%-5p %d{HH:mm:ss.SSS}] %m%n"/> </File>
|
3. RollingFile:支持日志滚动(生产环境首选)
RollingFile是生产环境最常用的 Appender,支持按时间、大小分割日志文件(避免单文件过大),并自动清理旧日志。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <RollingFile name="rollingLog" fileName="logs/app.log" <!-- 当前日志文件路径 --> filePattern="logs/archive/app-%d{yyyyMMdd}-%i.log.bz2" > <PatternLayout charset="UTF-8" pattern="[%-5p %d{yyyy-MM-dd HH:mm:ss.SSS}] %l [%m]%n"/>
<Policies> <TimeBasedTriggeringPolicy interval="1" <!-- 滚动间隔(单位与filePattern的时间粒度一致,此处1表示1天) --> modulate="true" /> <SizeBasedTriggeringPolicy size="100 MB"/> <CronTriggeringPolicy schedule="0 0 2 * * ?"/> </Policies>
<DefaultRolloverStrategy max="30"> <Delete basePath="logs/archive/" maxDepth="1"> <IfFileName glob="app-*.log.bz2"/> <IfLastModified age="7d"/> </Delete> </DefaultRolloverStrategy> </RollingFile>
|
filePattern说明:
格式中的%d{yyyyMMdd}决定时间滚动粒度(如yyyyMM表示按月,yyyyMMddHH表示按小时);%i用于同一时间粒度内多次滚动(如 1 天内文件超过大小,生成app-20240520-1.log、app-20240520-2.log)。
4. Filter:日志过滤机制
Filter用于控制哪些日志能通过 Appender 输出,常用ThresholdFilter(按级别过滤)和LevelRangeFilter(按级别范围过滤)。
1 2 3 4 5 6 7 8 9
| <RollingFile name="errorLog" ...> <ThresholdFilter level="ERROR" <!-- 阈值级别 --> onMatch="ACCEPT" onMismatch="DENY" /> </RollingFile>
|
- 过滤逻辑:
ACCEPT:接受日志,后续 Filter 不再执行;
DENY:拒绝日志,后续 Filter 不再执行;
NEUTRAL:中立(交给后续 Filter 判断)。
Loggers:日志器(控制日志流向)
<Loggers>包含多个<Logger>和一个<Root>(根日志器),用于指定不同类 / 包的日志级别和输出目的地。
1. Logger:特定类 / 包的日志器
针对指定类或包配置日志行为,优先级高于Root。
1 2 3 4 5 6 7
| <Logger name="com.example.service" <!-- 类或包名(如"com.example"表示该包下所有类) --> level="DEBUG" additivity="false" > <AppenderRef ref="rollingLog"/> </Logger>
|
level作用:只输出该级别及以上的日志(如level="INFO"则不输出 DEBUG 和 TRACE)。
2. Root:根日志器
所有未被特定<Logger>匹配的类 / 包,将使用Root的配置(默认日志器)。
1 2 3 4
| <Root level="INFO"> <AppenderRef ref="stdout"/> <AppenderRef ref="rollingLog"/> </Root>
|
3. 避免日志重复输出
当Logger的additivity="true"(默认)时,日志会同时输出到Logger关联的 Appender 和Root关联的 Appender,导致重复。解决方式:
- 为
Logger设置additivity="false";
- 确保
Logger和Root的 Appender 不重复。
完整配置示例(生产环境参考)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout charset="UTF-8" pattern="[%-5p %d{yyyy-MM-dd HH:mm:ss.SSS} %t] %l %m%n"/> </Console>
<RollingFile name="InfoLog" fileName="logs/info.log" filePattern="logs/archive/info-%d{yyyyMMdd}-%i.log.gz"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout charset="UTF-8" pattern="[%-5p %d{yyyy-MM-dd HH:mm:ss.SSS} %t %X{traceId}] %l %m%n"/> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <SizeBasedTriggeringPolicy size="50MB"/> </Policies> <DefaultRolloverStrategy max="30"> <Delete basePath="logs/archive/" maxDepth="1"> <IfFileName glob="info-*.log.gz"/> <IfLastModified age="15d"/> </Delete> </DefaultRolloverStrategy> </RollingFile>
<RollingFile name="ErrorLog" fileName="logs/error.log" filePattern="logs/archive/error-%d{yyyyMMdd}-%i.log.gz"> <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout charset="UTF-8" pattern="[%-5p %d{yyyy-MM-dd HH:mm:ss.SSS} %t %X{traceId}] %l %m%n"/> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="30"> <Delete basePath="logs/archive/" maxDepth="1"> <IfFileName glob="error-*.log.gz"/> <IfLastModified age="30d"/> </Delete> </DefaultRolloverStrategy> </RollingFile> </Appenders>
<Loggers> <Logger name="org.springframework" level="INFO" additivity="false"> <AppenderRef ref="Console"/> <AppenderRef ref="InfoLog"/> </Logger> <Logger name="org.mybatis" level="INFO" additivity="false"> <AppenderRef ref="Console"/> <AppenderRef ref="InfoLog"/> </Logger>
<Logger name="com.example" level="DEBUG" additivity="false"> <AppenderRef ref="Console"/> <AppenderRef ref="InfoLog"/> <AppenderRef ref="ErrorLog"/> </Logger>
<Root level="INFO"> <AppenderRef ref="Console"/> <AppenderRef ref="InfoLog"/> <AppenderRef ref="ErrorLog"/> </Root> </Loggers> </Configuration>
|
关键配置要点总结
- 日志级别控制:
生产环境建议Root级别设为INFO,避免DEBUG/TRACE的冗余日志;特定包(如业务层)可设为DEBUG便于调试。
- 日志滚动策略:
- 结合
TimeBasedTriggeringPolicy(按时间归档)和SizeBasedTriggeringPolicy(避免单文件过大);
- 通过
DefaultRolloverStrategy的Delete自动清理旧日志,防止磁盘占满。
- 日志格式设计:
包含时间、级别、线程名、位置、消息,分布式系统需加入%X{traceId}实现链路追踪。
- 性能优化:
- 日志文件使用压缩(如
.gz、.bz2)减少磁盘占用;
- 高并发场景启用 Log4j2 异步日志(需额外配置
AsyncAppender)。
- 避免重复输出:
为自定义Logger设置additivity="false",避免同时输出到Logger和Root的 Appender
v1.3.10