0%

log4j2配置

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"?>
<!-- status:Log4j2自身日志级别(如WARN,避免过多内部日志);monitorInterval:自动检测配置文件变更的间隔(秒) -->
<Configuration status="WARN" monitorInterval="30">
<!-- 日志输出目的地集合 -->
<Appenders>
<!-- 具体的Appender(如控制台、文件、滚动文件等) -->
<Appender name="控制台" ...>
<!-- 过滤器(可选) -->
<Filters>...</Filters>
<!-- 日志格式(必填) -->
<PatternLayout .../>
<!-- 滚动策略(仅滚动文件Appender需要) -->
<Policies>...</Policies>
<!-- 滚动规则(仅滚动文件Appender需要) -->
<DefaultRolloverStrategy .../>
</Appender>
</Appenders>

<!-- 日志器集合 -->
<Loggers>
<!-- 特定类/包的日志器 -->
<Logger name="com.example" level="INFO" additivity="false">
<AppenderRef ref="控制台"/> <!-- 关联Appender -->
</Logger>
<!-- 根日志器(默认日志器) -->
<Root level="INFO">
<AppenderRef ref="控制台"/>
</Root>
</Loggers>
</Configuration>

Appenders:日志输出目的地

<Appenders>定义日志的输出位置(如控制台、文件),每个<Appender>需指定name(唯一标识)和具体类型(如ConsoleFileRollingFile)。

1. Console:输出到控制台

最基础的 Appender,用于将日志输出到控制台(SYSTEM_OUTSYSTEM_ERR)。

1
2
3
4
5
6
7
<Console name="stdout" target="SYSTEM_OUT"> <!-- target默认SYSTEM_OUT,可选SYSTEM_ERR(错误流) -->
<!-- 日志格式 -->
<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" <!-- 是否追加(false则每次启动清空文件,默认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" <!-- 滚动后文件命名格式(%i为序号,bz2表示压缩) -->
>
<!-- 日志格式 -->
<PatternLayout charset="UTF-8" pattern="[%-5p %d{yyyy-MM-dd HH:mm:ss.SSS}] %l [%m]%n"/>

<!-- 日志滚动触发策略(满足任一条件即滚动) -->
<Policies>
<!-- 时间触发:按天滚动(依赖filePattern中的%d{yyyyMMdd}) -->
<TimeBasedTriggeringPolicy
interval="1" <!-- 滚动间隔(单位与filePattern的时间粒度一致,此处1表示1天) -->
modulate="true" <!-- 是否对齐到自然时间(如每天0点滚动,而非启动后24小时) -->
/>
<!-- 大小触发:单个文件超过100MB则滚动 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
<!-- 定时触发:按Cron表达式滚动(如每天凌晨2点) -->
<CronTriggeringPolicy schedule="0 0 2 * * ?"/>
</Policies>

<!-- 滚动规则(文件数量控制与旧日志删除) -->
<DefaultRolloverStrategy max="30"> <!-- 同一目录下最大滚动文件数(超过则删除最旧的) -->
<!-- 自动删除7天前的日志 -->
<Delete basePath="logs/archive/" maxDepth="1"> <!-- basePath:日志存档目录;maxDepth:递归深度 -->
<IfFileName glob="app-*.log.bz2"/> <!-- 匹配文件名 -->
<IfLastModified age="7d"/> <!-- 保留7天内的日志(d=天,h=小时,m=分钟) -->
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
  • filePattern说明
    格式中的%d{yyyyMMdd}决定时间滚动粒度(如yyyyMM表示按月,yyyyMMddHH表示按小时);%i用于同一时间粒度内多次滚动(如 1 天内文件超过大小,生成app-20240520-1.logapp-20240520-2.log)。

4. Filter:日志过滤机制

Filter用于控制哪些日志能通过 Appender 输出,常用ThresholdFilter(按级别过滤)和LevelRangeFilter(按级别范围过滤)。

1
2
3
4
5
6
7
8
9
<RollingFile name="errorLog" ...>
<!-- 只输出ERROR及以上级别日志 -->
<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" <!-- 日志级别(TRACE < DEBUG < INFO < WARN < ERROR < FATAL) -->
additivity="false" <!-- 是否继承Root的Appender(false=不继承,避免重复输出) -->
>
<AppenderRef ref="rollingLog"/> <!-- 关联的Appender -->
</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. 避免日志重复输出

Loggeradditivity="true"(默认)时,日志会同时输出到Logger关联的 Appender 和Root关联的 Appender,导致重复。解决方式:

  • Logger设置additivity="false"
  • 确保LoggerRoot的 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"?>
<!-- 自动检测配置变更(30秒),Log4j2自身日志级别为WARN -->
<Configuration status="WARN" monitorInterval="30">
<Appenders>
<!-- 控制台输出(INFO及以上) -->
<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>

<!-- 滚动文件:INFO级别日志 -->
<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"/> <!-- 保留15天日志 -->
</Delete>
</DefaultRolloverStrategy>
</RollingFile>

<!-- 滚动文件:ERROR级别日志 -->
<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"/> <!-- 错误日志保留30天 -->
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>

<Loggers>
<!-- 第三方框架日志控制(如Spring、MyBatis,避免DEBUG级别的冗余日志) -->
<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>

<!-- 应用核心包日志(DEBUG级别,便于调试) -->
<Logger name="com.example" level="DEBUG" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoLog"/>
<AppenderRef ref="ErrorLog"/>
</Logger>

<!-- 根日志器(默认INFO级别) -->
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoLog"/>
<AppenderRef ref="ErrorLog"/>
</Root>
</Loggers>
</Configuration>

关键配置要点总结

  1. 日志级别控制
    生产环境建议Root级别设为INFO,避免DEBUG/TRACE的冗余日志;特定包(如业务层)可设为DEBUG便于调试。
  2. 日志滚动策略
    • 结合TimeBasedTriggeringPolicy(按时间归档)和SizeBasedTriggeringPolicy(避免单文件过大);
    • 通过DefaultRolloverStrategyDelete自动清理旧日志,防止磁盘占满。
  3. 日志格式设计
    包含时间、级别、线程名、位置、消息,分布式系统需加入%X{traceId}实现链路追踪。
  4. 性能优化
    • 日志文件使用压缩(如.gz.bz2)减少磁盘占用;
    • 高并发场景启用 Log4j2 异步日志(需额外配置AsyncAppender)。
  5. 避免重复输出
    为自定义Logger设置additivity="false",避免同时输出到LoggerRoot的 Appender

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10