Andrey Regentov
Andrey Regentov

Reputation: 3737

How to define variables in spring's xmls to use in log4j.properties

Kind of a puzzle here.

I have an application in WAR. There are web.xml and application context.xml in there, and also there is log4j.properties. This WAR runs in tomcat.

There is a possibility to use some variables in log4j.properties, e.g. log4j.appender.file.File=${catalina.base}/logs/app.log

I want to define a variable in web.xml or context.xml and use it in log4j.properties. For example, somehow set version=1.1 and use log4j.appender.file.File=${catalina.base}/logs/app-${version}.log. It should not be an environment variable.

Can I do it without recompiling the app?

ADD shouldn't affect anything, but just in case...

Its web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     version="2.5"
     xmlns="http://java.sun.com/xml/ns/javaee">

<!-- Spring -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:context.xml</param-value>
</context-param>

<!-- log4j -->
<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
    <param-name>log4jRefreshInterval</param-name>
    <param-value>10000</param-value>
</context-param>
<context-param>
    <param-name>log4jExposeWebAppRoot</param-name>
    <param-value>false</param-value>
</context-param>
...
</web-app>

Upvotes: 15

Views: 2088

Answers (3)

FoxyBOA
FoxyBOA

Reputation: 5846

Make a subclass of org.springframework.web.util.Log4jConfigListenerthat expose version value as System variable (and of course you can pass the value via standard System/Java environment variable).

public class TestListener extends Log4jConfigListener{

    @Override
    public void contextInitialized(ServletContextEvent pEvent) {
        String value = pEvent.getServletContext().getInitParameter("version");
        String version = System.getProperty("version");
        if (version == null || version.trim().length()==0) System.setProperty("version", value);

        super.contextInitialized(pEvent);
    }
}

And fix your web.xml

 <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
              http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee">

    <!-- Spring -->
    ...
    <!-- log4j -->
    <listener>
        <listener-class>com.TestListener</listener-class>
    </listener>
    <context-param>
        <param-name>version</param-name>
        <param-value>1.1</param-value>
    </context-param>
    ...

Upvotes: 9

Miguel Martinez
Miguel Martinez

Reputation: 66

javabot's answer about declaring a context-param to set the variable is correct, but in order to retrieve it in your properties file you will need something like https://code.google.com/p/eproperties/ ("EProperties extends the standard java.util.Properties object and syntax to include things like: variable substitution, nesting, inclusion and lists.").

You may want to look at this previous question: Reference other variables in Java properties file

Best of luck to you in finding the solution!

Upvotes: 0

javabot
javabot

Reputation: 171

I think you can do this by declaring a context-param in web.xml and using that param name in the property file you want to put the version or whatever.

in web.xml

<context-param>
    <param-name>version</param-name>
    <param-value>1.1</param-value>
</context-param>

in property file

log4j.appender.file.File=${version}/logs/app.log

This should work with a server restart, no compilation needed.

You can also try setting a property from the xml and accessing ti from the property file.

in web.xml

<Properties>
    <Property name="version">1.1</Property>
</properties>

in property file

log4j.appender.file.File=${version}/logs/app.log

Upvotes: 0

Related Questions