Using system environment variables in log4j xml configuration

JavaXmlConfigurationLog4jEnvironment Variables

Java Problem Overview


Is it possible to reference system environment variables (as opposed to Java system properties) in a log4j xml configuration file?

I'd like to be able to do something like:

<level value="${env.LOG_LEVEL}" />

and have it get that from the system environment variables, so I can avoid having to pass in so many things with -D parameters.

Java Solutions


Solution 1 - Java

I tried to do that recently and couldn't get it to work. What I ended up doing is sending a variable at startup. So say you have an environment variable called $LOG_LEVEL:

<level value="${log_level}" />

and at startup...

java -Dlog_level=$LOG_LEVEL your_app

Solution 2 - Java

This syntax is documented only in log4j 2.X so make sure you are using the correct version. It does not work on the 1.X versions.

    <Appenders>
    <File name="file" fileName="${env:LOG_PATH}">
        <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
        </PatternLayout>
    </File>
</Appenders>

Solution 3 - Java

I think this is not supported, but basically you can do two things to bring in your environment variables:

  1. Use System.setProperty before Log4J gets configured

  2. Convert (your) environment variables to system properties in your launcher

The first option basically boils down to this:

for (Map<String,String>.Entry entry : System.getenv().entrySet()) {
  System.setProperty(entry.getKey(), entry.getValue());
}

... but the question is of course where to put this code. In particular if you're running within some sort of Tomcat container or similar, this might be troublesome.

The other largely depends on your environment. Basically if you have a shell script that starts your app, you can write some shell magic to set all environment variables as properties, or just the ones you need, e.g.:

java -DMY_ENV=$MY_ENV -DMY_OTHER_ENV=$MY_OTHER_ENV -cp ... com.example.Main

It's also possible to alter your server startup scripts to support this, e.g. catalina.sh or similar.

Solution 4 - Java

You need to put a colon between env and the name of the variable, like this:

<level value="${env:LOG_LEVEL}" />

Solution 5 - Java

Create a system variable. I prefer to use setenv.bat for such variables.

@echo off
rem app specific log dir
set "APP_LOG_ROOTDIR=../app/app-log"
exit /b 0

Add reference in log4j.xml file

<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
  <param name="Threshold" value="DEBUG" />
  <param name="MaxFileSize" value="512KB" />
  <param name="MaxBackupIndex" value="10" />
  <param name="File" value="${APP_LOG_ROOTDIR}/app.log"/>
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%d %-5p %c{1} %m %n" />
  </layout>
</appender>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDerek LewisView Question on Stackoverflow
Solution 1 - JavaEinarView Answer on Stackoverflow
Solution 2 - JavaShohamView Answer on Stackoverflow
Solution 3 - JavaMartin ProbstView Answer on Stackoverflow
Solution 4 - JavaDaniel EstradaView Answer on Stackoverflow
Solution 5 - JavatkollehView Answer on Stackoverflow