Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to configure logback logger levels on the command line?

Log4J allows you to pass the level you'd like particular loggers in your application to log at from the command line, e.g. "-Dlog4j.logger.com.whatever.MyClass=DEBUG". I can't find any similar facility in Logback. According to the FAQ, all it seems to allow you to do is set the level for the root logger by using variable substitution. Is there something I'm missing or does Logback just not support this? Thanks.

like image 458
bfancher Avatar asked Apr 23 '14 19:04

bfancher


2 Answers

Yes, seems there is no such feature. As I understand, it is partly because that logback configuration is more complex so quite difficult to achieve reasonable configuration flexibility by flat string properties. Partly because, imho, it encourages bad practice - placing too many system properties - leads to bloated run-scripts or command lines, more difficult to manage than separate logging configuration files.

However, I could suggest several options:

  • use ${sys.prop.var.name} substitutions in your logback.xml config file
  • copy logback.xml locally, modify it with desired logger levels and specify -Dlogback.configurationFile=/path/to/customised/logback.xml. Keep in mind that "Logback-classic can scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes". So, you even don't need to relaunch your process to change logging levels.
  • DIY: Add a code in your application which would read system properties and apply the properties to the logging levels during start up.
like image 94
kan Avatar answered Oct 13 '22 18:10

kan


I know this is an old question, but here is my solution code to initialize Logback Logger levels from SysProps, if anyone needs it. Note that it retrieves the Logback Logger using Slf4j's LoggerFactory. It uses a Java 8 lambda but could easily be translated to Java 7 or less.

You just have to add SysPropLogbackConfigurator.applyOnce() at the start of your main method. If called multiple time, the static initializer will prevent re-scanning the properties.

package com.yourpackage;  import org.slf4j.LoggerFactory; import ch.qos.logback.classic.Level;  /**  * Looks into System.properties for props -DLOG.loggerName=LEVEL to set Logback levels at startup  * If LEVEL is empty (setting -DLOG.loggerName without level), it erases a previously set level and will inherit from parent logger  */ public class SysPropLogbackConfigurator {      public static final String PROP_PREFIX = "LOG.";      public static void apply() {         System.getProperties().stringPropertyNames().stream().filter(name -> name.startsWith(PROP_PREFIX)).forEach(SysPropLogbackConfigurator::applyProp);     }      public static void applyOnce() {         OnceInitializer.emptyMethodToForceInit();//force static init. applySysPropsToLogback will be called only once     }      private static void applyProp(final String name) {         final String loggerName = name.substring(PROP_PREFIX.length());         final String levelStr = System.getProperty(name, "");         final Level level = Level.toLevel(levelStr, null);         ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(loggerName)).setLevel(level);     }      private static class OnceInitializer {         static {             apply();         }          static void emptyMethodToForceInit() {         };     } } 
like image 28
Benoît Avatar answered Oct 13 '22 20:10

Benoît