9

I declare loggers in my code like this:

Logger logger = LoggerFactory.getLogger(MyClass.class);

I would like to be able to change the log level of my loggers programmatically at runtime. I have tried iterating over the loggers in the repository via the LogManager, but it only applies the new log level to loggers that are instantiated in the code. If a new logger instance is created, it does not use the new log level. My requirement is such that the log level in my web application needs to be configurable via an Administrative GUI, and this new log level needs to apply to all loggers in my code (exclude third party library logging, e.g. JSF, Spring, Hibernate etc).

This is what I'm doing now which does not meet my requirements as it does not apply the log level to newly instantiated loggers:

Enumeration<Logger> currentLoggers = LogManager.getCurrentLoggers();
while(currentLoggers.hasMoreElements()) {
    Logger logger = currentLoggers.nextElement();
    if (StringUtils.startsWith(logger.getName(), "com.my.company")) {
        logger.setLevel(logLevel);
    }
}

I am using Log4j 1.2.17.

citress
  • 889
  • 3
  • 13
  • 35
  • You need to change your log4j configuration programmatically. Not only the already instantiated Loggers. See http://stackoverflow.com/a/4598829/982149 – Fildor Aug 26 '14 at 13:19
  • possible duplicate of [Dynamically Changing log4j log level](http://stackoverflow.com/questions/4598702/dynamically-changing-log4j-log-level) – Fildor Aug 26 '14 at 13:21
  • @Fildor, I'm still not sure what the solution is after reading that post. I can't do LogManager.getRootLogger().setLevel(Level.DEBUG); because it will change the root logger and that will affect all log levels including those from 3rd party libraries. – citress Aug 26 '14 at 13:27
  • My log4j is a bit rusty, but I think you can set the loglevel for "com.my.company" and it will affect all child Loggers. I'll get back to you in a Moment ... – Fildor Aug 26 '14 at 13:30
  • Didn't find the resource anymore, but as to my faded memory `LogManager.getLogger("com.my.company").setLevel(whateverloglevel)` should do the job. – Fildor Aug 26 '14 at 13:40
  • 1
    That seems to have worked. I tried that early on but felt like it wasn't working. Maybe something else was wrong. Now it seems to be working, thanks! If you post it as an answer I will accept it. – citress Aug 26 '14 at 14:15

1 Answers1

22

Didn't find the resource anymore, but as to my faded memory LogManager.getLogger("com.my.company").setLevel(whateverloglevel) should do the job.

All loggers that are created with LogManager.getLogger(MyClass.class) where MyClass is in com.my.company or in a subtree of that will be affected.

whateverloglevel is one of Level:

ALL
    The ALL has the lowest possible rank and is intended to turn on all logging.
DEBUG
    The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
ERROR
    The ERROR level designates error events that might still allow the application to continue running.
FATAL
    The FATAL level designates very severe error events that will presumably lead the application to abort.
INFO
    The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
OFF
    The OFF has the highest possible rank and is intended to turn off logging.
TRACE
    The TRACE Level designates finer-grained informational events than the DEBUG
WARN
    The WARN level designates potentially harmful situations.

Be aware that this probably does not work in log4j 2.

For (I think) version >= 2.4 see:

Fildor
  • 14,510
  • 4
  • 35
  • 67