1
votes

From here

You don’t need to declare separate loggers to achieve this. You can set the logging level on the AppenderRef element.

And xml example (part):

<Root level="trace">
  <AppenderRef ref="file" level="DEBUG"/>
  <AppenderRef ref="STDOUT" level="INFO"/>
</Root>

But I can't find a way to do it when I create configuration myself. For example I have consoleAppenderBuilder and rootLoggerBuilder:

AppenderComponentBuilder consoleAppenderBuilder = builder
    .newAppender("Stdout", "CONSOLE")
    .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);

RootLoggerComponentBuilder rootLoggerBuilder = builder
    .newRootLogger(Level.ERROR)
    .add(builder.newAppenderRef("Stdout"));

How to add console appender to root logger and define log level for appender. I am asking this because I want to add multiple appenders to root logger.

2
I understand that you wanted to know how to configure the appender level programmatically but it feels like this could be an XY Problem in that you may not really need to do programmatic configuration to achieve the results you want. Could you please explain why you want to configure log4j2 in this way? If you can avoid programmatic configuration then you can prevent your code from depending on the log4j2 implementation and instead rely on the public interface, which saves you some trouble in the long run.D.B.

2 Answers

1
votes

Below is one way of setting log level for each Appender in RootLogger -

AppenderComponentBuilder consoleAppenderBuilder = builder
    .newAppender("Stdout", "CONSOLE")
    .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);

RootLoggerComponentBuilder rootLoggerBuilder = builder
    .newRootLogger(Level.ALL)
    .add(builder.newAppenderRef("Stdout").addAttribute("level", Level.INFO));

If you have multiple appenders, below code can work -

RootLoggerComponentBuilder rootLoggerBuilder = builder
    .newRootLogger(Level.ALL)
    .add(builder.newAppenderRef("Stdout").addAttribute("level", Level.INFO)).add(builder.newAppenderRef("fileAppender").addAttribute("level", Level.ERROR));

The only point to remember is Appender log level can reduce logging Level given in logger but can not increase logging level.

Suppose in above example, level in RootLogger initialization is Level.ALL and for Stdout appender, it is Level.INFO. So, it will print logs of INFO level and above (WARN, ERROR). However, the reverse will not work i.e. if RootLogger has Level.INFO and Stdout appender has Level.All, in that case also, it will print logs of INFO level and above.

1
votes

As an alternative approach you could add a ThresholdFilter using the following example from the manual to guide you (it uses MarkerFilter but should be similar process).