2

I've been having trouble configuring log4j2 with Java.

I have a working XML config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="DEBUG">
<appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level - %msg%n" />
    </Console>
    <File name="DM_PREPUB" fileName="logs/41_2015/DM_PREPUB.log">
        <MarkerFilter marker="DM_PREPUB" onMatch="ACCEPT" onMismatch="DENY" />
        <PatternLayout>
            <pattern>%d %p %C{10} [%t] %m%n</pattern>
        </PatternLayout>
    </File>
    <File name="BACKUP" fileName="logs/41_2015/BACKUP.log">
        <MarkerFilter marker="BACKUP" onMatch="ACCEPT" onMismatch="DENY" />
        <PatternLayout>
            <pattern>%d %p %C{10} [%t] %m%n</pattern>
        </PatternLayout>
    </File>
</appenders>
<loggers>
    <logger name="foo.bar" level="DEBUG">
        <appender-ref ref="DM_PREPUB" />
        <appender-ref ref="BACKUP" />
    </logger>
    <root level="ALL">
        <appender-ref ref="Console" />
    </root>
</loggers>
</configuration>

As you can see, this config creates two FILE appenders with corresponding markers. Quite straightforward.

I tried and implemented the same config in Java, but with no luck:

    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
    builder.setStatusLevel(org.apache.logging.log4j.Level.ALL);
    builder.setConfigurationName("DMWorkflow");
    builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL).addAttribute("level", org.apache.logging.log4j.Level.DEBUG));
    // console appender
    AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
    appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%d{HH:mm:ss.SSS} [%t] %-5level - %msg%n"));
    builder.add(appenderBuilder);
    // main log appender
    appenderBuilder = builder.newAppender("DM_PREPUB" /*appender name*/, "FILE" /*appender type*/)
            .addAttribute("fileName", "logs/41_2015/DM_PREPUB.log");
    appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%d %p %C{10} [%t] %m%n"));
    appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.ACCEPT, Filter.Result.DENY).addAttribute("marker", "DM_PREPUB"));
    builder.add(appenderBuilder);
    // step appenders
    appenderBuilder = builder.newAppender("BACKUP" /*appender name*/, "FILE" /*appender type*/)
            .addAttribute("fileName", "logs/41_2015/BACKUP.log");
    appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%d %p %C{10} [%t] %m%n"));
    appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.ACCEPT, Filter.Result.DENY).addAttribute("marker", "BACKUP"));
    builder.add(appenderBuilder);
    // main logger
    LoggerComponentBuilder componentBuilder = builder.newLogger("foo.bar", org.apache.logging.log4j.Level.DEBUG).add(builder.newAppenderRef("DM_PREPUB"));
    // step loggers
    componentBuilder.add(builder.newAppenderRef("BACKUP"));
    builder.add(componentBuilder);
    builder.add(builder.newRootLogger(org.apache.logging.log4j.Level.ALL).add(builder.newAppenderRef("Stdout")));
    Configurator.initialize(builder.build());

In both cases, I instantiate the logger this way:

    logger = LogManager.getLogger("foo.bar");
    globalMarker = MarkerManager.getMarker("DM_PREPUB");

The Java config code does not seem that complicated, which is why I don't manage to see where I did wrong.

If you could be of any help, that could be great.

Thank you!

erwann

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
Erwann
  • 95
  • 2
  • 11

1 Answers1

3

What worked for me when I struggled with a similar problem was initializing the logger using:

((org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false)).start(builder.build());

I haven't tried your approach then though. My issue was that the loggers didn't write anything, and when debugging I found out the configuration I provided using the builder was never actually used since Log4j2 somehow decided it already uses the same configuration and doesn't need to reconfigure.

If the above doesn't help, try debugging to see what happens in both builder.build() and Configurator.initialize(). As far as I recall, my troubles were caused by AbstractLifeCycle.state flag that needed to be in state INITIALIZED but became STARTED too soon.

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • I works fine with this solution! I owe you big one for not having had to struggle like you did. I guess I should have thought of debugging first. – Erwann Mar 04 '16 at 11:10
  • This worked for me too. Not sure why this worked when I was trying to follow the reconfigure example with Configurator.initialize() here: https://logging.apache.org/log4j/2.x/manual/customconfig.html it never seemed to work and always used the default configuration no matter how I configured the builder. – QuestionableUser Oct 15 '16 at 00:01