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