Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

log4j2 configuration will not load custom pattern converter

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:

  1. Annotate it with @Plugin and @ConverterKeys
  2. Specify the plugin's category to be a "Converter"
  3. Include a static "newInstance(String[])" method
  4. Implement the "format" method
  5. 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?

like image 951
littlezz Avatar asked Jul 23 '14 19:07

littlezz


1 Answers

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.

like image 58
Remko Popma Avatar answered Nov 08 '22 09:11

Remko Popma