How to dynamically change log level in SLF4j OR Log4J

For SLF4J, this code will demonstrate how to control logger level programmatically (at run-time).

This answer assumes you are using Logback Classic:

  • Maven Central: https://search.maven.org/artifact/ch.qos.logback/logback-classic

Assuming default SLF4J configuration:

final Logger logger = LoggerFactory.getLogger(LoggerListener.class);
// These five statements will log.
logger.error("error");
logger.warn("warn");
logger.info("info");
logger.debug("debug");
logger.trace("trace");

final ch.qos.logback.classic.Logger logger2 =
    (ch.qos.logback.classic.Logger) logger;

@Nullable
final Level prevLevel = logger2.getLevel();
logger2.setLevel(Level.INFO);

logger.info("Change log level: [{}]->[{}]", prevLevel, Level.INFO);

// These three statements will log.
logger.error("error");
logger.warn("warn");
logger.info("info");
// These two statements will not log.
logger.debug("debug");
logger.trace("trace");

It is not possible to change the log level dynamically in slf4j, but some backends for slf4j support it, including log4j.

This solution worked for me:

org.apache.log4j.Logger logger4j = org.apache.log4j.Logger.getRootLogger();
logger4j.setLevel(org.apache.log4j.Level.toLevel("ERROR"));

(Source: http://prateep.info/2015/12/12/Dynamically-change-log-level-in-SLF4j-Log4J-with-Standalone-Java-Class/)

The disadvantage of this solution is that it uses the backend directly, which you're not supposed to do when using slf4j because the point of slf4j is to provide an abstraction away from the specific backend you're using.


Consider Logback http://logback.qos.ch/ - "a successor to the popular log4j project, picking up where log4j leaves off". If instructed to do so, logback-classic will scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes. Besides, you can control Logback's logging levels with JMX.