Stephane Grenier
Stephane Grenier

Reputation: 15927

sl4j and logback - Is it possible to programmatically set the logging level for package?

I'm able to programmatically set the logging level on the application with the following code, but is it also possible to do this on a package level, say com.somepackage.* where I want the level to be only ERROR rather than DEBUG or INFO on said package?

// Sets the logging level to INFO
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.INFO);

But I can't seem to find a way to set it on a package level...

Upvotes: 23

Views: 35045

Answers (4)

Deepak
Deepak

Reputation: 4052

In case you don't want to change the logback-classic to a compile-time dependency, here is some code that uses reflection to set this level assuming that logback is used as the slf4j runtime-binding. Here AbcClass is the class whose logger level you want to change to TRACE:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SomeClass {
private static final Logger logger = LoggerFactory.getLogger(SomeClass .class);
    public static void beforeEachTest() throws Exception {
        final Logger loggerInterface = LoggerFactory.getLogger(AbcClass.class);
        String loggerLevelNew = "TRACE";
        if (!loggerInterface.isTraceEnabled()) {
            try {
                Class<?> levelLogBackClass = Class.forName("ch.qos.logback.classic.Level");
                Method toLevelMethod = levelLogBackClass.getDeclaredMethod("toLevel", String.class);
                Object traceLvel = toLevelMethod.invoke(null, loggerLevelNew);
                Method loggerSetLevelMethod= loggerInterface.getClass().getDeclaredMethod("setLevel", levelLogBackClass);
                loggerSetLevelMethod.invoke(loggerInterface, traceLvel);
            } catch (Exception e) {
                logger.warn("Problem setting logger level to:{}, msg: {}", loggerLevelNew, e.getMessage());
                throw e;
            }
        }
    }
}

Something similar can be done for log4j and JDK logging to make this (kind-of) library agnostic

Upvotes: 3

Abhijit Sarkar
Abhijit Sarkar

Reputation: 24528

You can get the SLF4J logger for the package and cast it to Logback logger. Less code that @dimitri-dewaele's.

((Logger) LoggerFactory.getLogger("com.somepackage")).setLevel(DEBUG)

@nandu-prajapati's approach is similar, except that it sets the root logger level, not the one desired.

Upvotes: 2

Nandu Prajapati
Nandu Prajapati

Reputation: 129

You can do it by using logback..

Logger LOG = (Logger) org.slf4j.LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
LOG.setLevel(Level.WARN);

This solved my problem.

Upvotes: 8

Dimitri Dewaele
Dimitri Dewaele

Reputation: 10659

You should set the package name as logger-name

// Sets the package level to INFO
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
Logger rootLogger = loggerContext.getLogger("com.somepackage");
rootLogger.setLevel(Level.INFO);

You should be able to get the package name more elegant, but this is basically it. This follows the tree like hierarchy for the Logger Context: Logger Context

Upvotes: 41

Related Questions