dhalsim2
dhalsim2

Reputation: 963

How do you override a log4j2 configuration file with another log4j2 configuration file?

My current web application uses log4j 1.2, and I'd like to migrate to log4j2, but I haven't been able to figure out how to handle my particular use case.

In my web app's war file, I store a log4j configuration file which has reasonable defaults. My design is to search for a configuration file external to the war file which would override the configuration bundled with the war. That way logging configuration is configured at deployment time and can be different for each server.

Using log4j 1.2, this is accomplished via a ServletContextListener with the following method and it works great:

/**
 * Configures system-wide log4j logging system with log4j.xml from the
 * class path.  This overrides configuration from the default location in
 * Tomcat:  WEB-INF/classes
 */
private void configureLog4J() {
    URL url = ClassLoader.getSystemResource("log4j.xml");
    if (url != null) {
        DOMConfigurator.configure(url);
        log = org.apache.log4j.LogManager.getLogger(LDSContextListener.class);
        log.info("log4j.xml loaded from " + url);
    }
}

If I'm going to migrate to log4j2, how can I override the internal file with configuration from an external file? log4j2 doesn't have DOMConfigurator in its API.

Upvotes: 4

Views: 5621

Answers (3)

Dragos Ionut
Dragos Ionut

Reputation: 257

You can add an environment variable called LOG4J_CONFIGURATION_FILE while you start the application.

Upvotes: 1

dhalsim2
dhalsim2

Reputation: 963

I found a solution that doesn't exactly replicate what I had before, but comes close enough.

Instead of programmatically configuring log4j, I add log4j-web-2.0.jar to my classpath and add the following to my web.xml:

<context-param>
  <param-name>isLog4jAutoInitializationDisabled</param-name>
  <param-value>true</param-value>
</context-param>
<context-param>
  <param-name>log4jConfiguration</param-name>
  <param-value>file:///usr/jboss/ldsconf/log4j2.xml</param-value>
</context-param>

<listener>
  <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>

<filter>
  <filter-name>log4jServletFilter</filter-name>
  <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>log4jServletFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
  <dispatcher>ERROR</dispatcher>
  <dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
</filter-mapping>

where the log4jConfiguration context-param specifies where my external configuration file is. This isn't the same as the ClassLoader searching the classpath for the configuration file, but it still allows me to reference an external configuration file. Also, if this file isn't present, the system falls back to the internal configuration file, which is exactly what I wanted.

Reference: http://logging.apache.org/log4j/2.x/manual/webapp.html

Upvotes: 4

Remko Popma
Remko Popma

Reputation: 36754

I suggest you create a feature request on the Log4j2 Jira issue tracker.

Upvotes: -1

Related Questions