3

I wish to have a single WAR file that will work in different environments (like dev, ci and prod) and spring environments largely cater to our use cases. log4j per environment is one of the outstanding items. As suggested in other answers, we can have a log4j configuration per environment - but there is a lot of repetition in the files for each of the environments and the only kind of things that differ are minor properties like toAddress of SMTPAppender, etc.. Is there an easy way by which one can use a template-like log4j configuration file and have the parts that differ for each environment replaced at runtime? Maven will not work here because it will cause compile time choice.

One solution I can think of is to extend the Log4jConfigurer to read some environment variables viz. map of template key-value pairs and replace the template variables in the template file with the actual values before passing it down to the DOMConfigurator. Just wanted to check if there are simpler ways of doing it or if I am barking up a wrong tree from a best practices point of view.

Thanks in advance!

Community
  • 1
  • 1
Kilokahn
  • 2,281
  • 1
  • 25
  • 50
  • 1
    A non-template solution is to use entity references as noted in http://stackoverflow.com/questions/6116156/can-log4j-inherit-xml-from-a-base-root-element which I think does a decent job of reducing repetition. – Kilokahn Aug 12 '14 at 02:26
  • Could you explain why compile time can't help here? Do you mean that you want to create war only once and run it on all environments with -Denvironment=xxx property instead of building different war files for each environment? – Vadim Kirilchuk Jan 08 '15 at 16:46

1 Answers1

1

I don't fully understand your case but property placeholders should help: http://jvleminc.blogspot.ru/2008/05/avoid-absolute-path-in-log4j-properties.html

  1. Use a placeholder in the properties file when you indicate the appender file, for instance

    log4j.appender.file.File=${log4j.logFile}
    
  2. Pass this placeholder value as a VM parameter to the (web) application. The log4j engine will try to resolve the placeholder and eventually fall back on the System parameters, therefore, in our example:

    -Dlog4j.logFile=C:/logs/MyApplication.log
    

Btw, I think usually people externalize logging configuration, i.e. they use external log4j.properties file. Release engineers manage these configurations per environment. Also it gives an ability to change the file and restart an app, or in some cases allows to change some values even without restart.

Vadim Kirilchuk
  • 3,532
  • 4
  • 32
  • 49