javalogginglogbackapache-commons-config

How to set logback configuration file at runtime?


I would like to have a logback.xml file for production and another one with different parameters on my staging environment. My code is able to automatically know at runtime if it is on production or runtime. Is there a way to set the logback configuration file at runtime?


Solution

  • Method 1: Loading from different files

    You can hold two different configurations files and load the file for the specific enviroment with JoranConfiguratior#doConfigure at application startup.

    See http://logback.qos.ch/manual/configuration.html#joranDirectly. Example code also taken from there with modifications for your case:

    public class MyApp3 {
      final static String STAGING_CONFIGURATION = "/path/to/staging.xml";
      final static String PRODUCTION_CONFIGURATION  = "/path/to/production.xml";
    
      final static Logger logger = LoggerFactory.getLogger(MyApp3.class);
    
      public static void main(String[] args) {
        // assume SLF4J is bound to logback in the current environment
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
    
        // determine environmental specific configuration path
        final String path = isProdcution() ?  PRODUCTION_CONFIGURATION : STAGING_CONFIGURATION;
    
        try {
          JoranConfigurator configurator = new JoranConfigurator();
          configurator.setContext(context);
          // Call context.reset() to clear any previous configuration, e.g. default 
          // configuration. For multi-step configuration, omit calling context.reset().
          context.reset(); 
          configurator.doConfigure(path);
        } catch (JoranException je) {
          // StatusPrinter will handle this
        }
        StatusPrinter.printInCaseOfErrorsOrWarnings(context);
    
        logger.info("Entering application.");
    
        Foo foo = new Foo();
        foo.doIt();
        logger.info("Exiting application.");
      }
    }
    

    Of course, your code for getting the correct filename could be adjusted fitting your needs. Furthermore, there are some overloaded doConfigure methods (http://logback.qos.ch/apidocs/ch/qos/logback/core/joran/GenericConfigurator.html#doConfigure%28java.io.File%29) which takes InputStreams, Files and URLs as well.

    Method 2: Using conditionals in one file

    If you can determine your environment using logback's built-in properties or system properties, you can use conditional configurations:

    http://logback.qos.ch/manual/configuration.html#conditional

    <!-- if-then form -->
    <if condition="condition for your production">
        <then>
           ...
        </then>
        <else>
           ...
        </else>
    </if>