Log4j自定义过滤器在Appender内失效,全局配置却正常?
问题描述
我创建了如下自定义过滤器:
@Plugin(name = "EmptyMessageFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true) public class EmptyMessageFilter extends AbstractFilter { @PluginFactory public static EmptyMessageFilter createFilter() { return new EmptyMessageFilter(); } ... }
Log4j配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Properties> <Property name="LOG_PATTERN"> %d{yyyy-MM-dd HH:mm:ss.SSS} </Property> </Properties> <!-- 过滤器在此处可正常工作 --> <Filters> <EmptyMessageFilter/> </Filters> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true"> <PatternLayout pattern="${LOG_PATTERN}"/> <!-- 过滤器在此处无法工作 --> <Filters> <EmptyMessageFilter/> </Filters> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="ConsoleAppender"/> </Root> </Loggers> </Configuration>
该过滤器配置在Console Appender内部时无法工作,但配置在Appenders外部的全局Filters节点时可正常工作。根据Log4j 2.x官方文档,两种配置方式均应生效。RegexFilter、BurstFilter等内置过滤器在Appender内可正常使用,我未发现自定义过滤器与内置过滤器的差异,请问问题出在哪里?
问题原因与解决方案
问题出在自定义过滤器的elementType注解参数上。你当前设置的elementType = Filter.ELEMENT_TYPE仅对应全局过滤器的上下文,而Appender内部的过滤器需要对应Appender.ELEMENT_TYPE元素类型。
内置过滤器如RegexFilter、BurstFilter的注解中同时声明了多个elementType,因此能同时支持全局和Appender内部两种使用场景。
修改自定义过滤器的@Plugin注解,添加Appender.ELEMENT_TYPE即可解决问题:
@Plugin( name = "EmptyMessageFilter", category = Node.CATEGORY, elementType = {Filter.ELEMENT_TYPE, Appender.ELEMENT_TYPE}, // 同时支持全局和Appender内的过滤器场景 printObject = true ) public class EmptyMessageFilter extends AbstractFilter { @PluginFactory public static EmptyMessageFilter createFilter() { return new EmptyMessageFilter(); } ... }
原理说明
Log4j 2.x通过elementType标识插件可被加载的上下文环境:
- 全局
<Filters>节点对应的是Filter.ELEMENT_TYPE - Appender内部的
<Filters>节点对应的是Appender.ELEMENT_TYPE
你的自定义插件仅声明支持全局过滤器上下文,因此在Appender内部无法被正确识别和加载。
内容的提问来源于stack exchange,提问作者sge
相关产品推荐
相关产品推荐

