xenoterracide
xenoterracide

Reputation: 16837

Set root logger appender pattern with log4j programmatic API

I'm trying to configure the pattern of the Root Logger using one of the log4j programatic api's. This is what I have, it's removing the default logger and I know that reconfigure, setLevel and setRootLevel are working, but the new ConsoleAppender isn't actually logging anything

private static void configureLog4j(Level rootLevel, Map<String, Level> levelMap) {
    var pattern = PatternLayout.newBuilder().withPattern( "%highlight{[%t] %-5level: %msg%n%throwable}\n" ).build();
    var console = ConsoleAppender.createDefaultAppenderForLayout( pattern );
    var config = LoggerContext.getContext().getConfiguration();
    config.addAppender( console );

    var root = config.getRootLogger();
    for ( var appenderRef : root.getAppenderRefs() ) {
      root.removeAppender( appenderRef.getRef() );
    }
    root.addAppender( console, rootLevel, null );
    Configurator.setRootLevel( rootLevel );
    Configurator.setLevel( levelMap );
    Configurator.reconfigure(config);
  }

I tried the other API too, same luck there. How can I fix my code?

Here's a full link to my source, sorry, I've been working on it so the line number may change.

https://github.com/xenoterracide/brix/blob/master/src/main/java/com/xenoterracide/brix/Application.java#L108

Upvotes: 3

Views: 580

Answers (1)

s7vr
s7vr

Reputation: 75934

Update

It would appear the only way to programmatically configure log4j2 would be to create a new configuration using configuration builder. This way it will stop the default configuration and initialize with new configuration.

ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
AppenderComponentBuilder appenderBuilder = builder.newAppender("console", "CONSOLE").addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%highlight{[%t] %-5level: %msg%n%throwable}\n"));
builder.add(appenderBuilder);
builder.add(builder.newRootLogger(rootLevel).add(builder.newAppenderRef("console")));
levelMap.forEach((s, level) -> builder.add(builder.newLogger(s, level)));
Configurator.initialize(builder.build());

Original

Perhaps you mean to set the level and rootLevel after the logger is re-configured. The way you have is applied to the existing logger.

Configurator.reconfigure(config);
Configurator.setRootLevel( rootLevel );
Configurator.setLevel( levelMap );

Upvotes: 1

Related Questions