Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically change log level in SLF4j OR Log4J

Recently I encountered a situation where Application Loglevel changes dynamically. Application Admin can set it to INFO/DEBUG/ WARN from front end. Based on the log level choosen be him application logging must be changed.

I am sure loggers support this scenario. How can I achieve this?

like image 412
Narendra Avatar asked Nov 18 '12 18:11

Narendra


People also ask

How do you change the log level in slf4j?

When using log4j, the Logger. log(Priority p, Object message) method is available and can be used to log a message at a log level determined at runtime. We're using this fact and this tip to redirect stderr to a logger at a specific log level. slf4j doesn't have a generic log() method that I can find.

How do you change the logger level?

To change log levels as a root user, perform the following: To enable debug logging, run the following command: /subsystem=logging/root-logger=ROOT:change-root-log-level(level=DEBUG) To disable debug logging, run the following command: /subsystem=logging/root-logger=ROOT:change-root-log-level(level=INFO)

How do you change the log level in log4j2 at runtime?

You can set a logger's level with the class Configurator from Log4j Core. BUT be aware that the Configurator class is not part of the public API. If you wish to change the root logger level, do something like this : LoggerContext ctx = (LoggerContext) LogManager.


3 Answers

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.

like image 57
outofthecave Avatar answered Sep 19 '22 15:09

outofthecave


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.

like image 20
Evgeniy Dorofeev Avatar answered Sep 17 '22 15:09

Evgeniy Dorofeev


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");
like image 36
kevinarpe Avatar answered Sep 18 '22 15:09

kevinarpe