配置log4j的核心答案是:先确定你用哪个版本(1.x还是2.x),再根据日志场景选择properties或XML配置文件,最后完成Logger、Appender、Level、Layout四要素的组装这套流程跑通,日志就能按你的预期输出。
log4j1.x和log4j2.x选哪个更合适
很多人在搜索引擎里问“log4j配置教程”时,默认指的是老牌的log4j 1.x,但2026年的当下,log4j 2.x才是真正值得投入时间的版本,这个判断不是偏好问题,而是事实问题。
log4j 1.x已经停止维护多年,存在官方确认的远程代码执行漏洞,生产环境用它等于裸奔,而log4j 2.x重写了底层架构,支持异步日志、无锁设计,吞吐量比1.x高出数倍不止,对于新项目或者还在维护的老项目升级,答案没有悬念:直接用2.x。
如果你的诉求仅仅是“把日志打出来就行”,那1.x也够用,但代价是安全风险和性能瓶颈,业内专家指出,不少企业在2026年前后遭受的日志攻击事件,根源就是log4j 1.x没升级,别再走这条路了。
log4j核心配置流程详解
整个配置过程虽然涉及多个参数,但逻辑非常线性,用一句话概括:Logger定义谁记录日志,Appender决定日志写到哪,Level设定什么级别才记录,Layout控制日志长什么样,这四个要素缺一不可。
第一步:引入依赖
Maven项目在pom.xml中加入:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
Gradle项目在build.gradle中加入:
implementation 'org.apache.logging.log4j:log4j-core:2.20.0' implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
记得把版本号换成当前最新的稳定版,依赖不进来,后面的一切都是空谈。
第二步:选择配置文件类型
log4j 2.x支持四种配置格式:properties、XML、JSON、YAML,最常用的是properties和XML两种。
properties格式胜在简洁,适合日志需求不复杂的场景,XML格式结构清晰,支持更高级的配置项,比如Routing、RollingFile的复杂策略,下面分开说。
log4j properties配置的具体写法
在src/main/resources下创建log4j2.properties文件,一个完整的基础配置长这样:
name=MyAppConfig appender.console.type=Console appender.console.name=STDOUT appender.console.layout.type=PatternLayout appender.console.layout.pattern=[%p] %d{yyyy-MM-dd HH:mm:ss} [%t] %c{1}: %m%n appender.file.type=RollingFile appender.file.name=ROLLING_FILE appender.file.fileName=${sys:user.home}/logs/myapp.log appender.file.filePattern=${sys:user.home}/logs/myapp-%d{yyyy-MM-dd}-%i.log.gz appender.file.layout.type=PatternLayout appender.file.layout.pattern=[%p] %d{yyyy-MM-dd HH:mm:ss} [%t] %c{1}: %m%n appender.file.policies.type=Policies appender.file.policies.size.type=SizeBasedTriggeringPolicy appender.file.policies.size.size=10MB appender.file.strategy.type=DefaultRolloverStrategy appender.file.strategy.max=10 rootLogger.level=info rootLogger.appenderRef.stdout.ref=STDOUT rootLogger.appenderRef.file.ref=ROLLING_FILE
关键点拆解一下:
rootLogger.level=info表示根日志级别为INFO,低于这个级别的DEBUG日志不会输出Console类型Appender输出到控制台,适合开发调试RollingFile类型Appender实现按大小滚动,单个文件超过10MB自动归档- 归档文件保留最近10份,避免磁盘被日志蚕食
当你在网上搜“log4j怎么配置日志级别”时,修改rootLogger.level后面的值就是答案:从高到低依次是FATAL > ERROR > WARN > INFO > DEBUG > TRACE。
log4j XML配置的进阶玩法
XML配置文件默认为log4j2.xml,同样放在src/main/resources下,基础示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}-%i.log">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
<Logger name="com.example" level="DEBUG" additivity="false">
<AppenderRef ref="RollingFile"/>
</Logger>
</Loggers>
</Configuration>
注意<Logger name="com.example">这个配置:它单独指定了com.example包的日志级别为DEBUG,且additivity="false"表示日志不会向上传递给Root Logger,这招对定位特定包的bug非常有用。

配置生产环境的日志输出策略
本地开发时控制台日志随便打,但生产环境要是这么搞,不出三天磁盘就报警了,基于多年踩坑经验,生产配置要把握三个原则。
日志分级分文件存储
把ERROR日志和普通INFO日志分开存放,问题排查时只需翻看错误文件,避免海量普通日志淹没关键线索,你需要两个RollingFile Appender,一个过滤级别为ERROR,另一个输出INFO及以上级别。
在XML中启用Filter实现:
<RollingFile name="ErrorLog" fileName="logs/error.log" filePattern="logs/error-%d{yyyy-MM-dd}.log">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
ThresholdFilter是这里的主角:onMatch="ACCEPT" onMismatch="DENY"意味着只接受ERROR及以上级别的日志,这就是log4j2配置详解里的常见操作模式。
异步日志让性能起飞
同步日志虽然实现简单,但高并发场景下会阻塞业务线程,log4j 2.x提供的AsyncLogger优势明显,推荐在耗时敏感的业务里使用,启用方式不复杂,加入disruptor依赖,然后配置Loggers时增加asyncLogger相关设置。
更简单的做法是给配置根节点加一个系统属性引导:
<Configuration status="WARN" packages="com.example">
实际生产部署时,在启动命令中加入:
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
这条命令就是打开异步日志的开关,启用后,日志写入的耗时从毫秒级降到微秒级,业务响应时间几乎不受日志影响。
log4j常见报错排查
配置过程中一定会碰壁,这里把高频问题列出来。
配置文件没生效
看到控制台输出ERROR StatusLogger No log4j2 configuration file found.时,说明log4j没找到配置文件,检查两件事:第一,log4j2.properties或log4j2.xml确实放在classpath路径下(通常是resources目录);第二,文件命名拼写正确,尤其是2.x版本比1.x多了个2,写错就是找不到。
日志重复输出
同一个日志事件被打印了两次甚至多次,这种“复读机”症状最折腾人,多数情况下是因为Logger上设置了additivity="false"漏写,导致子Logger的输出向上传递,和Appender的直接输出构成重复,排查策略:检查每个自定义Logger是否漏设

additivity="false",或者Root Logger与自定义Logger引用了同一个Appender且传递属性为true。
中文日志乱码
控制台输出乱码通常是文件编码问题,在properties中给PatternLayout加上charset:
appender.console.layout.type=PatternLayout appender.console.layout.charset=UTF-8
XML格式对应写法是:
<PatternLayout charset="UTF-8" pattern="..."/>
配置了滚动却一直没有拆分
触发策略写了SizeBasedTriggeringPolicy,但文件超过10MB不滚动,这种情况往往是策略配置缩进或标签顺序引起解析问题,确认filePattern是否正确包含日期或计数器变量(%i),没有变量就无法生成新文件。
log4j2配置详解:从入门到实战的关键路径
如果你想在百度搜索中找到直接的“log4j2配置详解”而不依赖翻烂官方文档,记住下面这条完整路径:
- 理解API与Core分离:log4j-api提供接口,log4j-core提供实现,项目代码中只需面向api编程,配置和运行全靠core解析
- 配置文件自动加载:应用启动时,log4j2按classpath依次搜索
log4j2-test、log4j2.properties、log4j2.xml等命名 - 动态修改日志级别:2.x支持在运行期通过代码修改,无需重启应用:
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration config = context.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig("com.example");
loggerConfig.setLevel(Level.DEBUG);
context.updateLoggers();
这段代码将com.example包下日志级别动态调整为DEBUG,线上排障时少一次重启,少背一次变更审批单。
常见问题解答
log4j和slf4j是什么关系?
SLF4J是日志门面接口,log4j 2.x是具体实现,你可以通过slf4j调用log4j2,好处是后续切换日志框架无需改业务代码,集成时引入log4j-slf4j-impl依赖即可。
如何关闭某个类或第三方库的冗余日志?
在Loggers标签内配置Logger,为具体类或包单独设级别:
<Logger name="org.apache.http" level="WARN"/>
将org.apache.http调为WARN级别后,其内部的INFO级调试输出直接消失,日志量肉眼可见地减少。
log4j2漏洞修复目前什么状态?
log4j 2.17.0及更高版本修复了CVE-2021-44228(Log4Shell)等已知漏洞,生产项目务必保持版本不低于2.17.0,官方已从2.x的特定分支持续发布安全更新,同时配合JVM参数-Dlog4j2.formatMsgNoLookups=true可进一步加固防御面,该参数同样适用于2.10以上版本。

