如何在上下文范围内使用log4j2自定义过滤器对象



我正试图根据文档使自定义过滤器在自定义范围内工作
我开始认为以这种方式使用自定义筛选器时存在问题,因为默认筛选器被正确调用,而自定义筛选器没有被正确调用。我拥有的是:

ThresholdFilterCustom.java(与ThresholdFilter相同,仅用于调试(:

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.message.Message;
@Plugin(name = "ThresholdFilterCustom", category = "Core", elementType = "filter", printObject = true)
public final class ThresholdFilterCustom extends AbstractFilter {
private final Level level;
private ThresholdFilterCustom(Level level, Result onMatch, Result onMismatch) {
super(onMatch, onMismatch);
this.level = level;
}
public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
return filter(level);
}
public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
return filter(level);
}
public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
return filter(level);
}
@Override
public Result filter(LogEvent event) {
return filter(event.getLevel());
}
private Result filter(Level level) {
//    Look here! It should always match! not even filtering!
return onMatch;
}
@Override
public String toString() {
return level.toString();
}
/**
* Create a ThresholdFilterCustom.
* @param loggerLevel The log Level.
* @param match The action to take on a match.
* @param mismatch The action to take on a mismatch.
* @return The created ThresholdFilterCustom.
*/
@PluginFactory
public static ThresholdFilterCustom createFilter(@PluginAttribute(value = "level", defaultString = "ERROR") Level level,
@PluginAttribute(value = "onMatch", defaultString = "NEUTRAL") Result onMatch,
@PluginAttribute(value = "onMismatch", defaultString = "DENY") Result onMismatch) {
return new ThresholdFilterCustom(level, onMatch, onMismatch);
}
}

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Filters>
<ThresholdFilterCustom level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />
<!--      <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />-->
</Filters>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>

如果我取消注释

<!--  <ThresholdFilterCustom level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />-->

我没有在控制台中看到logger.debug记录的消息("logmessage"(

但是如果我取消注释

<!--  <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />-->

确实看到logger.debug记录的消息("logmessage"(,即使它们之间的行为应该相同。为什么会发生这种情况?这可能是一个log4j2问题吗?

在使用调试器时,我看到过滤器函数甚至没有在自定义过滤器中调用,但自定义过滤器正在实例化。

如果我把它们放在记录器里,它们就会正常工作。但当把它们放在上下文范围内时,它们就不起作用了。

答案在这里。

对于在这里着陆的人们:这是在这里解决的。简而言之,这些方法的javadoc似乎是混合在一起的。要实现上下文范围的筛选器,应该覆盖其他方法,即不进行筛选的方法(LogEvent事件(。

根据Ralph Goers的评论:

插件正在正确构建和调用。然而您没有覆盖所有的筛选方法。大多数默认为返回NEUTRAL,这就是该方法在本例中所做的操作。很可能将AbstractFilter默认为调用其他方法,这样就不需要重写那么多方法。

他的另一个答案:

当评估全局筛选器时,LogEvent尚未建造。因此,如果你只想支持全局过滤器,那么你需要实现所有不接受LogEvent的方法。同样,要在其他地方使用Filter,您只需要实现接受LogEvent的方法。是的,我想Javadoc有向后

关于默认方法,我的意思是有3个筛选明确返回NEUTRAL的方法。

public Result filter(final Logger logger, final Level level, final
Marker marker, final Message msg,final Throwable t); 
public Result filter(final Logger logger, final Level level final Marker 
marker, final Object msg,final Throwable t);
public Result filter(final Logger logger, final Level level, final Marker 
marker, final String msg, final Object... params);

因此,所有这三个都需要在过滤器,例如您创建的过滤器。接受的所有其他方法Logger最终调用上面接受varargs的方法对象(即Object数组(作为最后一个参数。它会使我觉得前两个方法也应该调用第三个方法作为默认值,而不是返回NEUTRAL(空档(。然而,这意味着失去了其中一个参数是可丢弃,我相信这就是它按原样实现的原因并不是说你需要对此做任何事情,除了那个权利现在您必须实现上面的所有3个方法。

最新更新