Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting properties programmatically from Log4j2 XML config

Tags:

java

log4j2

In my Log4j2 config file, I have this:

<?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 create custom loggers. I need to access the value of "baseDir" and change it. I've tried using getProperties from the context like this:

LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration configuration = context.getConfiguration();
configuration.getProperties();

But the map that comes back has the keys "hostname" and "contextName". Not the properties map that I was looking for.

I thought that I might be able to get it from the rootLogger:

LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration configuration = context.getConfiguration()
for (Property p : configuration.getRootLogger().getPropertyList())
{
    ...
}

But this yields a NullPointerException because getPropertyList returns null.

So, how can I access the property with the name "baseDir" so that I can programmatically create a new logger, but with a different base directory?

like image 703
FrustratedWithFormsDesigner Avatar asked May 23 '17 18:05

FrustratedWithFormsDesigner


1 Answers

The class Configuration, which is returned by context.getConfiguration() is not a kind of PropertyConfiguration class. It cannot be used for access of log4j2.xml values, since it is the very different Configuration class, tailored for logging settings.

It is possible to extract baseDir definition into separate properties file. This provides the common source for both programmatic and non-programmatic log4j configuration: programmatically it can be accessed as a regular property configuration file; log4j2 configuration can access it as a properties lookup.

This looks something like this:

  1. The external property file logsCommons.properties is located in the same folder with log4j2.xml and has the property:

    baseDir=log-dir
    
  2. The log4j2xml is defined as following:

    <Properties>
        <Property name="baseDir">${bundle:logsCommons:baseDir}/</Property>
        <Property name="defaultLogfileName">default-log-file</Property>
    </Properties>
    

From the OP:

In addition to moving the value of baseDir to a properties file and references it as ${bundle:logsCommon:baseDir} as described above, I did this to get to my actual solution:

get the StrSubstitutor:

String baseDirVar = configuration.getStrSubstitutor().getVariableResolver().look‌​up("baseDir"); 

Then I needed to do a replacement:

String baseDir = configuration.getStrSubstitutor().replace(baseDirVar);

Now I can reliably get (and modify when necessary) the base directory for logging that now comes from the properties file.

like image 138
asch Avatar answered Oct 05 '22 23:10

asch