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:
- Annotate it with @Plugin and @ConverterKeys
- Specify the plugin's category to be a "Converter"
- Include a static "newInstance(String[])" method
- Implement the "format" method
- Specify the plugin package with the configuration's "packages" parameter.
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?