Home > coding, java > Reconfigure log4j 1.x without restart

Reconfigure log4j 1.x without restart

Disclaimer: This blog post is about log4j 1.x. which is by now a dormant project and not recommended for new projects. Logback and log4j 2.x support dynamic configuration changes at runtime via a simple attribute in their respective config files (see related log4j 2.x and logback docs). Please consider upgrading your logging backend to one of those libraries and use them in combination with the slf4j logging facade API.

Support for dynamic logging config changes at runtime is useful when you want to debug an application without restarting it: You can change settings in your logging config file, like log levels, appenders, log output formats, etc. and the logging framework automatically notices the change and reconfigures itself after a certain delay.

Good old log4j 1.x supports this, but you have to programatically set it up, typically somewhere in the start-up code of your Java application, using

  • DOMConfigurator.configureAndWatch(..) if you use log4j.xml
  • PropertyConfigurator.configureAndWatch(..) if you use log4j.properties

Please note that the log4j 1.x FAQ does not recommend doing this in a JEE container:

“Because the configureAndWatch launches a separate watchdog thread, and because there is no way to stop this thread in log4j 1.2, the configureAndWatch method is unsafe for use in J2EE environments where applications are recycled.”

The following example code works both for log4j.xml or log4j.properties files, as long as they are in the classpath as file resources, i.e. not packaged inside a jar:

    public static enum ConfigFileType {
         xml, properties
    }

    public void configureLogging(ConfigFileType configFileType) {
        final URL configFile = getClass().getResource("/log4j." + configFileType);

        if (configFile != null && "file".equals(configFile.getProtocol())) {
            final int scanDelayMinutes = getSystemProperty("log4j.config.rescan.delay.minutes", 2);
            final long scanDelayMillis = scanDelayMinutes * 60 * 1000;

            switch (configFileType) {
                case xml:
                    DOMConfigurator.configureAndWatch(configFile.getPath(), scanDelayMillis);
                    break;
                case properties:
                    PropertyConfigurator.configureAndWatch(configFile.getPath(), scanDelayMillis);
                    break;
            }
        }
    }

    private static int getSystemProperty(String name, int defaultValue) {
        try {
            return Integer.parseInt(System.getProperty(name));
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

You can override the default rescan delay as a system property option in your java command, for example:

java -Dlog4j.config.rescan.delay.minutes=5 [..]

The period is in minutes to prevent too much rescanning. Log4j uses a “FileWatchdog” class that repeatedly checks File#lastModified(). On some filesystems – like ReiserFS on Linux – scan delays of less than a minute can cause problems (thanks to Rod Oliveira for pointing this out).

Advertisements
Categories: coding, java Tags: , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: