2

I am trying to load log4j2.xml or properties file from a specific location which will be provided at runtime. This is part of a migration from log4j 1.x to log4j 2.x version. I have seen there are lots of changes in the logging configuration loading sequences in log4j2. So right now after searching I have the following methods below -

1 -

 Configurator.reconfigure(new URI("URI of your file"));

2 -

// import org.apache.logging.log4j.core.LoggerContext;
LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
File file = new File("path/to/a/different/log4j2.xml");

// this will force a reconfiguration
context.setConfigLocation(file.toURI());

But they say that LoggerContext class is not part of the public API, is it still the case now ?

3-

InputStream inputStream = new FileInputStream("C:/path/to/log4j2.xml");
ConfigurationSource source = new ConfigurationSource(inputStream);
Configurator.initialize(null, source);

4- Or simply

Configurator.initialize(null, "/path/to/log4j2.xml");

I am confused if all of these are viable or are to be used in different scenarios and have different outcomes.

Also the functions that I am trying to replace are DOMConfigurator and PropertyConfigurator. I know log4j2 will find configurations automatically in classpath but incase I have multiple configuration files for different environments etc or scenarios or the configuration file is outside the classpath, somewhere else on the system - I am trying to use these above functions to do it. Please help as I am stuck here, thank you.

Srikar Rao
  • 57
  • 5

1 Answers1

2

If no LoggerContext is associated with the caller, all these methods have the same effect: they create a LoggerContext and configure it using the configuration source provided.

The 4 methods start to differ if there is a LoggerContext associated with the caller. This can happen if any LogManager's get* method was called before (e.g. in a static initializer). If this happens, the first two methods will replace that context's configuration, while the last two are no-ops.

PropertyConfigurator and DOMConfigurator in Log4j 1.x worked differently: unless you used log4j.reset=true key they modified the previous configuration. Although the two classes have been ported to the newest log4j-1.2-api, the "reset" semantic is not implemented and they behave like Configurator.reconfigure restricted to a single configuration format.

Remark: Configurator.reconfigure tries to guess the configuration format to choose the appropriate ConfigurationFactory. Since both Log4j 2.x and Log4j 1.x have the properties and XML formats, all properties and XML files will interpreted as native Log4j2 configuration files. Check this question for a workaround.

Piotr P. Karwasz
  • 12,857
  • 3
  • 20
  • 43
  • Thanks for the answer, this solves the confusion to a large extent. So bottom line is if I have changed my log4j 1.x XML and properties files to the new log4j2.x format, I can load these configurations before the application starts using Configurator.initialize() right ? – Srikar Rao Mar 27 '22 at 16:29
  • _"Before the application starts"_ is hard to achieve, since usually even the main class has a static logger field. However, if the configuration file is called `log4j2.properties` (or `log4j2.xml` if you prefer a less messed-up format), Log4j 2 will pick it up automatically (see [automatic configuration](https://logging.apache.org/log4j/2.x/manual/configuration.html#AutomaticConfiguration)) and you don't need to do anything at all. – Piotr P. Karwasz Mar 27 '22 at 18:23
  • thanks for the reply, yep I am aware about the automatic loading of the log4j2.xml. Only problem here for me is that the log4j2.xml is not in classpath, its in the WEB-INF folder and not inside the classes folder under it. In this case I do need to load it via the path programatically right ? – Srikar Rao Mar 27 '22 at 23:36
  • 1
    I would still try a couple of alternatives before falling back to programmatic configuration: 1. the [Log4j2 system property](https://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties) `log4j2.configurationFile`, 2. a custom [ConfigurationFactory](https://logging.apache.org/log4j/2.x/manual/extending.html#ConfigurationFactory). And if programmatic configuration is needed I would rather use `Configurator.reconfigure`. – Piotr P. Karwasz Mar 28 '22 at 05:29
  • thank you again for following up, will try these alternate options and replace configure with reconfigure, as it seems like the safer one to use. – Srikar Rao Mar 28 '22 at 08:18
  • Is there anyway to mimic the behavior of the absence of the old log4j.reset=true parameter ? Because I have a situation now to modify the current configuration, and on the official log4j2 website I see they are using context.getConfiguration(); then use FileAppender.createAppender method to create the appender then add it to the existing configuration, but now its seems like the createAppender method is deprecated. Can I still use the .createAppender method, or are there any alternatives ? – Srikar Rao Apr 02 '22 at 19:18
  • I have figured it out no issue, thanks – Srikar Rao Apr 02 '22 at 23:56