views:

236

answers:

3

For an application which is deployed on a large number of machines I took the decision to deploy a standard log4j.xml file with the application package, just to make sure that have the same settings are present everywhere : appenders, categories, levels.

This does have the downside that when modifying the levels locally we risk losing the changes on re-deploy or living with old settings. In practice, the only thing we need to change are the logger levels, most of the time 1 of them, so I'm looking for a solution which allows me to override just the levels per-installation.

How can I override the log4j levels without changing the original log4j.xml file?

+2  A: 

Set the environment variable log4j.configuration to point to an external file. This way if you re-deploy, the external file is no touched or changed and therefore your configuration is not lost.

For reference, see the Default Initialization Procedure section in the log4j manual.

matt b
So your suggestion is to copy the file then point the application ( temporarily ) to the new file?
Robert Munteanu
My suggestion is to store your log4j settings in a directory that is outside your app server so you don't have to worry about changes being lost during a re-deploy or undeploy, and using log4j.configuration environment variable to tell log4j where the file is. Nothing "temporary" about it.
matt b
In other words, override the default lookup behavior (of the webapps classpath, which is WEB-INF/classes, the common app server lib, etc) by setting the path yourself.
matt b
Now I understand. My problem is that I want the default file with usually some very minor , temporary, changes.
Robert Munteanu
+1  A: 

If you still want to have a shared main configuration, you could consider adding something to the application that allowed the Log4J logger levels to be changed after initialization. You could invoke these changes either via JMX, getting the overrides from a centralized source, or simply by periodically reading a local installation-specific override file (if present), depending on what infrastructure support your application can rely on.

Take a look at this for some more information:

Trevor Tippins
+1  A: 

I used to solve such problems by introducing another indirection into log4j properties file. For example specifying like

log4j.appender.CONSOLE.Threshold = %level%.

At run time, first thing I was doing is replacing the placeholders in memory, or sticking in the defaults. This way log4j configuration never changed throughout all deployments, including developers, QA and even production. Every target would have its main set of configuration parameters, amongst them would be %placeholders% for the level. These parameters would either come with the installer, or each user would keep main configuration aside while pulling the new version to work with. But log4j configuration never changes and nobody touches is except developers who involved directly with it.

May be my explanation is a bit too complicated... think of it as a Spring PropertyPlaceholderConfigurer and apply it to log4j configuration :)

It's a bit of coding, but really simple and solve lots of problems down the road.

Dima