0
votes

I have a project which uses log4j for logging. We have a log4j.xml file which controls the log level. I would like to have another log4j.local.xml which I plan to add to gitignore file that takes precedence over normal log4j.xml once it is present. This was on local builds, I can have a log level set to my liking but once the project is checked in and built (on Jenkins for example) and deployed normal log4j.xml setting get used since log4j.local.xml will not be there.

EDIT: Application does not have any configuration to specify settings file or anything for log4j. I assume the logging framework has some defaults that are being used. Also, application is using Java code for Spring configuration and not an XML file.

3
What's your question? - SubOptimal
How can achieve the result I am looking for - have a local log4j.xml that is not part of the project (i.e. in the git ignore file) and that files gets used over regular log4j.xml that is part of the project when I build a local project. - Mensur

3 Answers

3
votes

You could usespring's MethodInvokingFactoryBean to tell log4j where to look for the log4j config.

Here is an example using springs xml configuration:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="org.springframework.util.Log4jConfigurer"/>
    <property name="targetMethod" value="initLogging"/>
    <property name="arguments">
        <list>
            <value>${log.properties}</value>
        </list>
    </property>
</bean>

Then each environment will be able to have a different log4j properties file.

edit

Example of java config

@Bean
public MethodInvokingFactoryBean methodInvokingFactoryBean(@Value("${log.properties}") String location) {
    MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
    methodInvokingFactoryBean.setTargetClass(Log4jConfigurer.class);
    methodInvokingFactoryBean.setTargetMethod("initLogging");
    methodInvokingFactoryBean.setArguments(new Object[]{location});
    return methodInvokingFactoryBean;
}
0
votes

It depends how you read the configuration file.

If you use the default way, the file is searched in the classpath

change in developement the classpath so the development configuration
is found first

If you specify the configuration file by a JVM option (e.g. Log4j 2 ™ uses -Dlog4j.configurationFile=path/to/log4j.xml)

instead of using a hardcoded path use an environment variable and
change that setting in development to the development configuration
file

If you use another way, you should provide more information.

0
votes

At the start of your application you can try this:

import java.net.URL;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

public class LogginConfig {
    public static void initLoggin() {
        final URL localLog4jConfig = LogginConfig.class.getResource("/log4j.local.xml");
        if (null != localLog4jConfig) {
            System.out.println("using local log4j-configuration");
            DOMConfigurator.configure(localLog4jConfig);
        } else {
            System.out.println("using Log4j-default");
        }
    }

    public static void main(final String[] args) {
        initLoggin();
        Logger.getLogger(LogginConfig.class).debug("helloooooo");
    }
}

If log4j.local.xml can be found, it will be used. Otherwise Log4j's standard lookup procedure will be used.

Ignore the System.out statements :) This answer is like EricF's answer, just without spring.

I would have upvoted SubOptimal's answer, but first I need some reputations ;-)