如何修复Log4j2配置使不同日志级别分别存入独立文件?
解决Log4j2日志级别独立分文件问题
你的问题出在Filters的配置逻辑错误,导致info.log中混入了warn级别的日志。Log4j2的ThresholdFilter是阈值过滤,设置level="info"会**接受info及所有更高级别(warn、error)**的日志,原配置里的过滤规则顺序和匹配逻辑完全不对,才会出现级别交叉的情况。
下面是修正后的完整log4j2.xml配置,核心是给每个RollingFile配置精准的级别过滤,确保每个日志文件只写入对应级别的日志:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Properties> <Property name="PID">%pid</Property> <Property name="LOG_DIRECTORY">/media/edoyou/HDD/Kanan/k2s-project/k2sbeauty/logs</Property> <Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property> <Property name="LOG_LEVEL_PATTERN">%5p</Property> <Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property> <Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD} </Property> <Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} ${sys:PID} --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD} </Property> </Properties> <Appenders> <Console name="Console" target="SYSTEM_OUT" follow="true"> <PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}"/> </Console> <!-- 仅写入INFO级别日志 --> <RollingFile name="InfoFile" fileName="${LOG_DIRECTORY}/info.log" filePattern="${LOG_DIRECTORY}/logs/info-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="${sys:FILE_LOG_PATTERN}"/> <Policies> <SizeBasedTriggeringPolicy size="10 MB"/> </Policies> <DefaultRolloverStrategy max="10"/> <Filters> <!-- 先拒绝所有高于INFO的级别(WARN、ERROR) --> <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/> <!-- 接受INFO级别,拒绝更低级别(如DEBUG) --> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> </RollingFile> <!-- 仅写入ERROR级别日志 --> <RollingFile name="ErrorFile" fileName="${LOG_DIRECTORY}/error.log" filePattern="${LOG_DIRECTORY}/logs/error-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="${sys:FILE_LOG_PATTERN}"/> <Policies> <SizeBasedTriggeringPolicy size="10 MB"/> </Policies> <DefaultRolloverStrategy max="10"/> <Filters> <!-- 拒绝所有低于ERROR的级别(INFO、WARN) --> <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/> <!-- 接受ERROR级别 --> <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> </RollingFile> <!-- 仅写入WARN级别日志 --> <RollingFile name="WarnFile" fileName="${LOG_DIRECTORY}/warn.log" filePattern="${LOG_DIRECTORY}/logs/warn-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="${sys:FILE_LOG_PATTERN}"/> <Policies> <SizeBasedTriggeringPolicy size="10 MB"/> </Policies> <DefaultRolloverStrategy max="10"/> <Filters> <!-- 拒绝ERROR级别 --> <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/> <!-- 拒绝INFO及以下级别 --> <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/> <!-- 接受WARN级别 --> <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> </RollingFile> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> <AppenderRef ref="InfoFile"/> <AppenderRef ref="WarnFile"/> <AppenderRef ref="ErrorFile"/> </Root> </Loggers> </Configuration>
核心修改说明
- 每个日志文件的
Filters按先拒后收的逻辑配置:先排除所有不符合目标级别的日志,最后只接受目标级别 - 使用
NEUTRAL让过滤逻辑继续执行下一个规则,直到明确返回ACCEPT或DENY - 避免了原配置中
ThresholdFilter直接接受高级别日志的问题,确保每个文件只保留对应级别的内容
内容的提问来源于stack exchange,提问作者EDOYou
相关产品推荐
相关产品推荐

