I am trying to create a custom pattern converter for log4j 2.0, but am having issues getting my log4j configuration to recognize the pattern. Here is the custom converter:
package com.test.log4j.plugins;
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.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
@Plugin(name="MarkerNamePatternConverter", category="Converter")
@ConverterKeys({"markername"})
public class MarkerNamePatternConverter extends LogEventPatternConverter {
public static MarkerNamePatternConverter newInstance(final String[] options) {
return new MarkerNamePatternConverter("markername", "markername");
}
protected MarkerNamePatternConverter(String name, String style) {
super(name, style);
}
@Override
public void format(LogEvent event, StringBuilder toAppendTo) {
Marker marker = event.getMarker();
if (marker != null) {
// MarkerPatternConverter appends Marker.toString()
// which includes the parents of the marker. We just
// want the marker's name
toAppendTo.append(marker.getName());
}
}
}
And here is my log4j configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" packages="com.test.log4j.plugins">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern=" %-6level %markername %d{YYYY-MM-dd HH:mm:ss} %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="console"/>
</Root>
</Loggers>
</Configuration>
Note that I have included the package which contains the custom converter in my configuration, the lack of which seems to be a common cause of issues when using custom plugins.
When test code is executed, the configuration status output does not indicate that the plugin is loaded or found, and log4j treats the %markername as if it is the "%marker" conversion pattern followed by "name". For example,
Marker marker = MarkerManager.getMarker("TEST");
log.info(marker, "test message");
produces the following output:
INFO TESTname 2014-07-23 14:47:57 test message
I tried changing the conversion key a value that did not start with a standard conversion pattern, e.g. "fmarker", and when executed log4j produces the following error:
2014-07-23 14:44:55,814 ERROR Unrecognized format specifier [fmarker]
2014-07-23 14:44:55,816 ERROR Unrecognized conversion specifier [fmarker] starting at position 18 in conversion pattern.
INFO %fmarker 2014-07-23 14:44:55 test message
Documentation indicates that plugins are gathered at build time rather than runtime, but I haven't found anything that indicates that I need to do something specific to get my custom converter to be found other than to:
There was documentation for a Maven plugin, but my simple test is just a basic Java project developed in Eclipse.
Any ideas on what I am doing wrong?
To make a long story short, since version 2.0-rc2, the packages attribute does not work any more. Instead, there is an annotation processor in log4j-core that will (should?) run during the build and will generate a metadata file for your custom plugins in your jar file. When log4j2 starts it will look for the metadata file in all jar files and quickly discover all available plugins.
The annotation processor works when compiling with Maven or with plain javac, but it may not work well when compiling in Eclipse. You need to enable annotation processing with right-click on a project > Properties > Java Compiler > Annotation Processing.
Still, I am not 100% sure this will work from Eclipse. For now, one alternative is to build your custom plugin with Maven.
I will try to make the packages attribute work again in an upcoming release.
This issue is tracked here: https://issues.apache.org/jira/browse/LOG4J2-741
UPDATE (7/28) This is fixed in trunk and will be included in the 2.0.1 release.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With