Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

logback.xml : overriding root level for one class only

Tags:

java

xml

logback

Given the following root in logback.xml:

<root level="INFO">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
</root>

defining the following logging rule:

<logger name="com.myproject.mypackage.MyClass" level="DEBUG">
   <appender-ref ref="STDOUT" />
</logger>

The log level in myclass won't be DEBUG, because the root level is info. But I want to see debug logs in this particular class ONLY. Is that achieveable without changing the root level (which would cause the app to vomit debug logs from all over the place)?

EDIT: I tried this as well:

<logger name="com.myproject" level="INFO"/>
<logger name="com.myproject.mypackage.MyClass" level="DEBUG">

<root level="DEBUG">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
</root>

So the idea was to set the root to debug so everything is DEBUG, but set everything under 'com.myproject' to info so the log level really is INFO, but set MyClass to DEBUG. It didn't work :(

like image 915
Attila Neparáczki Avatar asked Feb 23 '17 10:02

Attila Neparáczki


People also ask

What is root in Logback xml?

In a Logback. xml file, all the configuration options are enclosed within the <configuration> root element. In the root element, you can set the debug=true attribute to inspect Logback's internal status. You can also configure auto scanning of the configuration file by setting the scan=true attribute.

Where should the Logback xml be?

In a Spring Boot application, you can put the Logback. xml file in the resources folder. If your Logback. xml file is outside the classpath, you need to point to its location using the Logback.

Does slf4j use Logback?

Native implementation of slf4j is logback, thus using both as logger framework implies zero memory and computational overhead.


1 Answers

"Root" level does not restrict levels of other loggers, it merely sets the default. So <root level="INFO"> and <logger name="some.name" level="DEBUG"> are perfectly suitable together, and you don't need to relax the "root" level. So both examples should log on debug level for logger named com.myproject.mypackage.MyClass. So if your configuration logs something and does not log from com.myproject.mypackage.MyClass, the problem should be in another place.

Also, if you want some logger to log into its own appender only, as in the first example, you should use additivity="false" attribute on logger, otherwise it will log to both root appenders and logger-specific appenders.

For example:

import org.slf4j.LoggerFactory;

class Scratch {
    public static void main(String[] args) {
        LoggerFactory.getLogger("some.logger").info("info msg");
        LoggerFactory.getLogger("another.logger").info("info msg");
        LoggerFactory.getLogger("another.logger").error("error msg");
    }
}

logback.xml:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>STDOUT: %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="STDOUT2" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>STDOUT2: %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="some.logger" level="info" additivity="false">
        <appender-ref ref="STDOUT2" />
    </logger>

    <root level="error">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

Result:

STDOUT2: 16:58:58.973 [main] INFO  some.logger - info msg
STDOUT: 16:58:58.979 [main] ERROR another.logger - error msg
like image 124
Konstantin Pelepelin Avatar answered Oct 21 '22 06:10

Konstantin Pelepelin