I'm attempting to implement and configure a custom Filter in Log4J2 - based on ThresholdFilter, but intended to do more. I've seen topics on custom appenders, which follow the same plugin annotation syntax, but haven't found a topic on custom fitlers.
MyCustomFilter.java (based on ThresholdFilter)
@Plugin(name = "MyCustomFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
public class MyCustomFilter extends AbstractFilter {
private static final long serialVersionUID = 1L;
private final Level level;
private MyCustomFilter(final Level level, final Result onMatch, final Result onMismatch) {
super(onMatch, onMismatch);
this.level = level;
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, final Object... params) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg, final Throwable t) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg, final Throwable t) {
return filter(level);
}
@Override
public Result filter(final LogEvent event) {
return filter(event.getLevel());
}
private Result filter(final Level level) {
return level.isMoreSpecificThan(this.level) ? onMatch : onMismatch;
}
@Override
public String toString() {
return level.toString();
}
/**
* Create a MyCustomFilter.
*
* @param level
* The log Level.
* @param match
* The action to take on a match.
* @param mismatch
* The action to take on a mismatch.
* @return The created MyCustomFilter.
*/
@PluginFactory
public static MyCustomFilter createFilter(@PluginAttribute("level") final Level level, @PluginAttribute("onMatch") final Result match,
@PluginAttribute("onMismatch") final Result mismatch) {
final Level actualLevel = level == null ? Level.ERROR : level;
final Result onMatch = match == null ? Result.NEUTRAL : match;
final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
return new MyCustomFilter(actualLevel, onMatch, onMismatch);
}
}
log4j2.xml
LoggingRunner.java
public class LoggingRunner {
public static void main(String[] args) {
Logger logger = LogManager.getLogger("com.me.test.logger");
logger.fatal("Fatal");
logger.error("Error");
logger.debug("Debug");
logger.info("Info");
System.out.println("end it");
}
}
The configuration syntax seems to match that in the Apache documentation and mimics ThresholdFilter (a working, provided filter). If I place it as shown, as a Context level filter, I don't see any errors, but the filter isn't invoked or applied.
If I move my custom filter tag inside an Appender (which is possible with out-of-the-box filters, I get 2015-03-24 16:20:11,713 ERROR AppenderRef contains an invalid element or attribute "MyCustomFilter".
Based on Apache Log4J2 documentation and examples in the log42j core source, I thought this would work.
What am I doing wrong?
解决方案
Can you show your config's first line, the element?
You can specify to make log4j's internal logging appear on the console, which may help troubleshoot the issue.
Perhaps log4j has trouble finding your plugin.
When you compile your plugin a serialized plugin listing file is created. This file contains the name of your plugin and the classname in binary format. If this file is included in the jar containing your plugin class, log4j can find your plugin. Another way to help log4j find your plugin is to specify a packages attribute your config file:
...
For more detail, see this manual page on how the PluginManager tries to locate plugins.