Search code examples
javalog4j2configuration-files

How often do you need to set the configuration file for log4j2?


I have several classes within a package and several packages within my project. For those files that are inherited, within the parent class is

 { // File location for log4j2.xml
    System.setProperty("log4j.configurationFile",
        "file:\\\\" + System.getProperty("user.dir") + "\\Properties\\log4j2.xml");
}

And yet, I see ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging.

So, obviously, once isn't enough.

So what is the general rule that I need to set the system property of log4j.configurationFile?

  • Once per package?
  • Once per class?
  • Each parent/base class, regardless of the package?
  • Or something else?

What's best practice for multiple classes and packages?


Solution

  • Log4j 2 configures itself on initialisation i.e. whenever a Logger instance is first created within an instance of a JVM, approximately ... the first class in your application which declares a Logger instance causes Log4j 2 to initialise itself. So, the answer to this question ...

    How often do you need to set the configuration file for log4j2?

    ... is once.

    The issue reported in your OP: No log4j2 configuration file found. Using default configuration is caused by Log4j being unable to find the configuration file you attempted to point it at. This issue is not caused by not 'setting the configuration file' often enough.

    According to the docs Log4j will look for its configuration source as follows:

    1. Log4j will inspect the "log4j.configurationFile" system property and, if set, will attempt to load the configuration using the ConfigurationFactory that matches the file extension.
    2. If no system property is set the properties ConfigurationFactory will look for log4j2-test.properties in the classpath.
    3. If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.
    4. If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or log4j2-test.jsn in the classpath.
    5. If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the classpath.
    6. If a test file cannot be located the properties ConfigurationFactory will look for log4j2.properties on the classpath.
    7. If a properties file cannot be located the YAML ConfigurationFactory will look for log4j2.yaml or log4j2.yml on the classpath.
    8. If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or log4j2.jsn on the classpath.
    9. If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.
    10. If no configuration file could be located the DefaultConfiguration will be used. This will cause logging output to go to the console.

    If your attempt to set log4j.configurationFile was successful then option 1 would be engaged but that attempt is not successful, we know this because the error message you quote tells us that Log4j is falling through to option 10.

    I would suggest running your application with -Dlog4j.configurationFile=/path/to/log4j2.xml or ensuring that the log4j2.xml is on your application's classpath. The idea of littering your code with System.setProperty(...) calls feels like an anti pattern and is likely to be quite brittle since any static Logger which is instanced before the System.setProperty(...) call will result in Log4j initialising itself before it knows about your config file location.