微信优化

weixinyouhua

log4j配置详解有哪些内容?log4j配置文件怎么配置

2026-09-25 10:52:54

Log4j配置的核心在于三件事:定义日志级别、绑定输出端(Appender)、决定日志格式(Layout),推荐直接用log4j2的XML配置,一条配置即可搞定按天滚动和异步写入。

老项目里常常见到log4j.properties,维护起来像在翻旧账本,本文从这套配置说起,再对比log4j2的XML写法,最后落到生产环境的滚动策略和性能调优,你不用从头看文档,照着下面的模块抄就行。

log4j.properties配置详解:老项目为何需要升级?

log4j.properties是Log4j 1.x时代的配置文件,键值对风格,简单直白,但Log4j 1.x早已停止维护,业内专家指出,继续使用它在现在意味着高风险漏洞得不到官方修复,log4j.properties配置详解”表面是学语法,实际上是为了让你能看懂老代码,并计划迁移到log4j2。

两种配置文件的直观区别如下:

  • log4j.properties:用log4j.rootLogger=INFO, stdOut定义根Logger,用log4j.appender.stdOut=org.apache.log4j.ConsoleAppender定义输出端。
  • log4j2.properties:键名变成rootLogger.level和appender.rolling.type,语法不兼容,但能用属性文件驱动log4j2。
  • log4j2.xml:目前最常用的写法,结构清晰,支持异步日志和条件过滤。

log4j日志级别怎么设置?五种级别选择指南

日志级别决定了哪些消息能落盘,按从低到高排列:TRACE、DEBUG、INFO、WARN、ERROR、FATAL,级别越低,输出越啰嗦。

在实际项目里,多数情况下这样设:

# log4j 1.x 写法
log4j.rootLogger=INFO, fileAppender
  • DEBUG:本地调试时用,配合IDE查看SQL和参数。
  • INFO:生产环境默认级别,记录启动、关闭、关键业务流转。
  • ERROR:只记录异常和失败,适合告警监控。
  • FATAL:通常仅用于进程致命的错误,使用频率很低。

有个常见误区:把根Logger设为DEBUG后,子Logger里写WARN,子包日志会变成WARN,而其他包仍然是DEBUG,因为log4j的继承机制是“子覆盖根”,这是特征,不是Bug。

properties配置里的三个坑

  • 键名大小写敏感,log4j.rootLogger和Log4j.RootLogger是两回事。
  • 文件编码默认用平台字符集,中文日志乱码时记得指定log4j.appender.fileAppender.encoding=UTF-8。
  • 路径中的${user.dir}是相对于进程启动目录,不是项目根目录,部署环境不一样就会“找不到日志文件”。
  • log4j配置详解有哪些内容?log4j配置文件怎么配置

log4j.properties看似简单,但每个键背后的Appender生命周期和刷新机制都需要理解,这也是为什么log4j2配置教程里,官方更推荐XML。

log4j2配置教程:从XML到异步日志

log4j2的XML配置把Logger、Appender、Layout拆成XML节点,比Properties更直观,下面是一份经过生产验证的最小骨架,你直接复制改路径就好。

log4j2.xml配置的基本骨架

<?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/app-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100MB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>
  • Configuration status:log4j2自身日志输出级别,设为WARN可避免刷屏。
  • PatternLayout:定义日志格式,%msg%n是消息和换行。
  • RollingFile:核心滚动文件Appender,按时间和大小两种策略同时触发。

log4j2按天滚动日志配置的两种写法

“按天滚动”是运维最常用的需求,目的是让单日日志独立成文件,方便排查和备份,roll策略有两种主流写法:

纯时间触发

<Policies>
    <TimeBasedTriggeringPolicy/>
</Policies>

配合filePattern="./logs/app-%d{yyyy-MM-dd}.log",每天零点切割,不压缩。

时间+大小双触发

<Policies>
    <TimeBasedTriggeringPolicy/>
    <SizeBasedTriggeringPolicy size="500MB"/>
</Policies>

这种策略更保险:白天流量突增,单日文件超过500MB也会触发滚动,避免打开文件时卡顿,此时

log4j配置详解有哪些内容?log4j配置文件怎么配置

filePattern需要加上%i序号,如app-%d{yyyy-MM-dd}-%i.log,否则文件会互相覆盖。

注意:max属性在DefaultRolloverStrategy中控制保留的备份数量,最大值为10代表最多保留10个历史文件,超出后自动删除最老的,这个值要依据磁盘空间调,别随意拍脑袋。

log4j2异步日志配置注意事项

异步日志能降低业务线程的IO阻塞,但配置不当反而丢日志,核心做法是启用AsyncLogger,需要引入disruptor依赖,XML中修改为:

<AsyncLogger name="com.example" level="INFO" includeLocation="false">
    <AppenderRef ref="RollingFile"/>
</AsyncLogger>
  • includeLocation="false":不记录代码行号,性能大幅提升,但查日志时看不到方法名。
  • Intel下AsyncLogger默认使用全局队列,多个Logger间会互相影响。

行业共识认为,异步日志能显著降低高吞吐服务的响应延迟,但前提是你接受日志丢失的极小概率,对交易类系统,建议同步写WARN和ERROR,异步写INFO和DEBUG,用ThresholdFilter实现。

生产环境日志格式与性能调优

日志格式不是好看而已,它直接决定排障效率,生产环境里,行日志需要包含时间、线程、级别、类名和消息,常用占位符有:

  • %d:时间,可配格式如{yyyy-MM-dd HH:mm:ss.SSS}。
  • %t:线程名。
  • %-5level:左对齐级别,占5字符。
  • %logger{36}:类名缩写。
  • %X{traceId}:读取MDC里的TraceId,全链路追踪时必配。
  • %throwable:完整堆栈。

一个推荐格式:

%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} [%X{traceId}] - %msg%n

日志文件备份与清理策略

很多项目只配滚动,不配清理,运行半年后磁盘满,log4j2的DefaultRolloverStrategy提供Delete配置:

<DefaultRolloverStrategy max="30">
    <Delete basePath="${baseDir}" maxDepth="1">
        <IfFileName glob=".log.gz"/>
        <IfLastModified age="7d"/>
    </Delete>
</DefaultRolloverStrategy>
  • max=30:最多30个文件。
  • Delete:删除7天前的压缩文件。
  • basePath:要扫描的目录,必须与filePattern的目录一致。
  • log4j配置详解有哪些内容?log4j配置文件怎么配置

注意:Delete只能处理不再写入的文件,正在写入的日志文件处于锁定状态,不会被误删。

log4j2配置文件不生效?先从加载顺序排查

配置写了但日志行为没变,这是开发阶段最高频的问题,log4j2有严格的配置加载顺序,按优先级从高到低:

  1. log4j2-test.properties、log4j2-test.yaml、log4j2-test.json、log4j2-test.xml
  2. log4j2.properties、log4j2.yaml、log4j2.json、log4j2.xml
  3. 系统属性-Dlog4j.configurationFile=路径指定的文件

如果你的log4j2.xml放在resources根目录,且没有test文件,那它一定会被加载,不生效时,先看控制台是否有ERROR StatusLogger报错,再检查项目里是否残留了log4j.properties它会被log4j2的桥接模块误读,产生干扰。

配置了Root Logger为何没有输出

通常是这两个原因:

  • 子Logger显式指定了丢日志的Appender,且additivity="false"切断了向根Logger的传递。
  • Filter误伤,比如某个Filter把所有INFO级别都拒绝了。

用-Dlog4j2.debug=true启动,控制台会打印每个Logger和Appender的关联状态,这是最实在的排查手段。

Q&A:log4j配置常见问题解答

log4j2配置文件和log4j.properties能不能共存?

能共存,但不建议,旧项目迁移时,log4j2会优先读取自己的文件,但历史依赖中如果存在log4j-over-slf4j或slf4j-log4j12,类加载顺序会混乱,最好的方式是删掉log4j.properties,只保留一套日志配置。

生产环境log4j2怎么关闭debug日志?

把<Root level="INFO">作为基准,再检查业务代码里是否调用Logger.debug输出敏感参数,如果第三方库的INFO日志太多,用<Logger name="org.apache.http" level="WARN"/>单独压级别,关闭所有DEBUG输出的有效方法是在配置中加入<ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>,放在Appender下即可。

log4j和slf4j是什么关系?

slf4j是日志门面,没有任何实现;log4j2是具体实现,代码里写LoggerFactory.getLogger时,运行时绑定的是log4j2提供的log4j-slf4j-impl依赖,如果绑定错误,无论log4j2配置教程写得多漂亮,日志都走不到Appender里。

相关文章

2024年,SaaS软件行业碰到获客难、增长慢等问题吗?

我们努力让每一次邂逅总能超越期待