There is the following xml log4j configuration file:

<?xml version="1.0" encoding="UTF-8"?> <Configuration trace="true" debug="true" info="true" warn="true"> <Appenders> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> </Console> <MyCustomAppender name="toStringProperty" > <PatternLayout pattern=":%m%n" /> </MyCustomAppender> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="STDOUT"/> </Root> <!-- <Logger name="com" level="debug"> <AppenderRef ref="STDOUT"/> </Logger> --> <Logger name="com.oaks" level="info"> <AppenderRef ref="toStringProperty"/> </Logger> </Loggers> </Configuration> 

The problem is that the logging level for the Root log depends on the level property of the "com.oaks" , which in itself is very strange.

Accordingly, if it is necessary to output a log of the debug level and higher to the console, you have to set the same level for the custom log, and it requires the info level.

I tried to create a separate log for the console (framed with a comment), but the effect is the same.

Please explain why this can happen and how then you need to properly adjust the levels for the logs.

  • Is the rootLogger itself used? Where? How do you initialize? - Sergey Mitrofanov
  • @SergeyMitrofanov. Maybe I don’t understand something, but I initialize the logger like this: public static final Logger LOG = LogManager.getLogger (% className%); - I. Perevoz
  • If% className% lies in the com.oaks package or in the nested one with respect to it, then it will inherit the logger settings for com.oaks if its personal logger is not defined. But for loggers from the com.foo package, either the com or root logger should work. The logger itself can be obtained separately Logger ROOT_LOG = LogManager.getRootLogger (); in any class - Sergey Mitrofanov
  • @SergeyMitrofanov. However, this does not explain why the level of the custom logger eliminates the level of the root logger, since The root in the hierarchy is at the top. - I. Perevoz
  • one
    In this case, the opposite is true. Read the source. Everything is described there and examples in the tables are logging.apache.org/log4j/2.0/manual/architecture.html - Sergey Mitrofanov

2 answers 2

Hello XML configuration with explanations:

 <?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n" /> </Console> <Console name="toStringProperty" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m 'toStringProperty'%n" /> </Console> </Appenders> <Loggers> <Logger name="com.oaks.A" level="info" additivity="false"> <AppenderRef ref="toStringProperty" /> </Logger> <Root level="debug"> <AppenderRef ref="STDOUT" /> </Root> </Loggers> </Configuration> 

Add a verification class:

 public class A { private Logger logA = LogManager.getLogger(this.getClass()); public static void main(String... d) { A a = new A(); a.logA.debug("debug a"); a.logA.info("info a"); a.logA.error("error a"); B b = a.new B(); b.logB.debug("debug b"); b.logB.info("info b"); b.logB.error("error b"); } class B { private Logger logB = LogManager.getLogger(this.getClass()); } } 

so:

when you specify a logger level, you filter messages (data transferred to a Logger object). The filtering principle is as follows: all messages above the specified level will be discarded (and therefore will not go further! (for example, to the root logger)) Filtering levels:

(top) ALL -> TRACE -> DEBUG -> INFO -> WARN -> ERROR -> FATAL -> OFF

From the above, your personal logger tuned to a lower level discards DEBUG level messages.

  • Thanks for the explanation. Tell me, how is it necessary to set up logging in order to display messages in a custom log a level lower than in the console? - I. Perevoz
  • one
    @ I.Perevoz To solve this problem, you should understand the filters - Peter Slusar

Thank you Peter Slusar and Sergey Mitrofanov.

The essence of the config has been reduced to the following:

 <?xml version="1.0" encoding="UTF-8"?> <Configuration trace="true" debug="true" info="true" warn="true"> <Appenders> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> </Console> <MyCustomAppender name="toStringProperty" > <PatternLayout pattern=":%m%n" /> <!-- здесь появился фильтр --> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> </MyCustomAppender> </Appenders> <Loggers> <Root level="debug" > <!-- оба аппендера находятся в рут-логе --> <AppenderRef ref="STDOUT"/> <AppenderRef ref="toStringProperty"/> </Root> </Loggers> </Configuration>