Getting properties programmatically from Log4j2 XML configuration
In my Log4j2 config file I have the following:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" strict="true" name="XMLConfig" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="baseDir">log-dir/</Property>
<Property name="defaultLogfileName">default-log-file</Property>
</Properties>
Now, in some of my code, I am creating my own logs. I need to access the "baseDir" value and change it. I tried to use getProperties
from context like this:
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration configuration = context.getConfiguration();
configuration.getProperties();
But the returned map has keys "hostname" and "contextName". Not the property map I was looking for.
I thought that I could get it from rootLogger:
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration configuration = context.getConfiguration()
for (Property p : configuration.getRootLogger().getPropertyList())
{
...
}
But this gives a NullPointerException because getPropertyList returns null.
So how can I access a property named "baseDir" so that I can programmatically create a new log, but with a different base directory?
source to share
The class configuration returned by context.getConfiguration () is not a kind of PropertyConfiguration class. It cannot be used to access log4j2.xml values ββas it is a very different configuration class for logging settings.
You can extract the baseDir definition into a separate properties file. This provides a common source for both programmatic and non-programmatic log4j configuration: programmatically it can be accessed programmatically as a regular property configuration file; The log4j2 config can refer to it as a property lookup.
It looks something like this:
-
The external properties file logsCommons.properties is located in the same folder with log4j2.xml and has the property:
baseDir=log-dir
-
The log4j2xml file is defined as follows:
<Properties> <Property name="baseDir">${bundle:logsCommons:baseDir}/</Property> <Property name="defaultLogfileName">default-log-file</Property> </Properties>
From OP:
In addition to moving the baseDir value into the properties file and referencing it like ${bundle:logsCommon:baseDir}
above, I did this to get to my actual solution:
get StrSubstitutor:
String baseDirVar = configuration.getStrSubstitutor().getVariableResolver().lookββup("baseDir");
Then I needed to do the replacement:
String baseDir = configuration.getStrSubstitutor().replace(baseDirVar);
Now I can reliably get (and change if necessary) the base directory for logging, which now comes from the properties file.
source to share