Log4j2如何配置实现仅含指定关键词的日志写入对应日志文件
问题解答
完全可以实现「仅当日志消息包含特定文本时,才将对应日志条目写入指定日志文件」的需求,你当前配置不生效的核心原因是组件使用错误:
ScriptPatternSelector的作用是根据日志内容选择不同的输出格式,不满足匹配条件的日志会走默认格式继续写入文件,不会被过滤丢弃,所以不带confirm关键词的日志还是会存到confirm.log里,达不到过滤效果。
正确实现方案
Log4j2的日志准入过滤逻辑需要通过Filter组件实现,给confirmFile Appender添加对应过滤器即可,以下提供两种可落地的实现方式:
方案1:使用RegexFilter(无脚本、性能更优,推荐)
直接使用Log4j2内置的正则过滤器,匹配消息中包含confirm的内容,匹配成功则允许写入,匹配失败则直接拒绝写入,不需要引入额外脚本依赖。
你只需要将原有confirmFile的配置替换为如下内容即可:
<RollingFile name="confirmFile" fileName="logs/confirm.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log" immediateFlush="true"> <!-- 过滤器:匹配包含confirm的日志,不匹配的直接拦截不写入 --> <RegexFilter regex=".*confirm.*" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n"/> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="10 MB"/> </Policies> </RollingFile>
方案2:使用ScriptFilter(适合复杂判断逻辑场景)
如果后续需要叠加更复杂的过滤规则,可以使用脚本过滤器,注意过滤器要直接放在Appender节点下,不要嵌在PatternLayout内部;另外获取日志消息内容要调用getFormattedMessage(),避免参数化日志场景下判断失效:
<RollingFile name="confirmFile" fileName="logs/confirm.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log" immediateFlush="true"> <!-- 脚本过滤器直接挂载在Appender下 --> <ScriptFilter onMatch="ACCEPT" onMismatch="DENY"> <Script name="ConfirmFilter" language="bsh"><![CDATA[ // 读取格式化后的完整日志文本做匹配 return logEvent.getFormattedMessage().contains("confirm"); ]]></Script> </ScriptFilter> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n"/> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="10 MB"/> </Policies> </RollingFile>
补充说明
- 你代码中
LogManager.getLogger("confirmFile")的写法不影响过滤逻辑,当前confirmFileAppender挂载在Root Logger上,所有Logger输出的日志只要满足过滤条件都会写入该文件,可根据实际业务需求调整Logger的挂载关系。 - 原有
allFileAppender不需要做任何修改,会正常存储全量日志,不受confirmFile过滤器的影响。 - 配置修改后重启应用,你代码中三条带
confirm关键词的日志会正常写入confirm.log,最后一条printing normal text with error会被过滤器拦截,不会出现在confirm.log中。
内容的提问来源于stack exchange,提问作者xxestter
相关产品推荐
相关产品推荐

