Our project uses Log4J, configured via log4j.properties file. We have multiple production servers, which log to different log files, so that the logs can be differentiated. So log4j.properties for node 1 looks like this:
...
log4j.appender.Application.File=D:/logs/application_1.log
...
log4j.appender.tx_info.File=D:/logs/tx_info_1.log
...
while the log4j.properties for node 2 looks like
...
log4j.appender.Application.File=D:/logs/application_2.log
...
log4j.appender.tx_info.File=D:/logs/tx_info_2.log
...
We already use Maven profiles for generating our server configuration. Up to now it contained several distinct log4j.properties files which differed only in the log file names as shown above. I would like to generate these files with Maven using a resource template file like this:
...
log4j.appender.Application.File=${log.location}/application${log.file.postfix}.log
...
log4j.appender.tx_info.File=${log.location}/tx_info${log.file.postfix}.log
...
It is easy to run Maven multiple times with different ${log.file.postfix}
values to generate a single different log property file each time. However, what I would like is to generate a distinct property file (with the name/path different) for each server in one build. I am fairly sure this can be done, e.g. via the antrun plugin, but I am not familiar with that. What is the simplest way to achieve this?
Here are some approaches that you can try:
use the antrun plugin, and the
copy
task to make duplicates of your resource file in thegenerate-resources
phase. An example of using the antrun plugin is given in the answer to this SO question on copying with maven. You could even use ant's property expansion to expand each ${log.file.postfix} to a distinct value, either the literal values, 1,2,3 etc. or unique placeholders, ${log.file.postfix1}, ${log.file.postfix2} which are finally replaced when maven does the resource filtering.Rather than using antrun, use your version control system to set up multiple copies of the same file. You can then run multiple instances of the resources:copy-resources goal, each with different property values configured, and a different target file name.
Although this is a bit old, I came across the thread recently and would like to propose an updated solution using the iterator-maven-plugin. An overview is found here: http://khmarbaise.github.io/iterator-maven-plugin/
A specific example of how you can accomplish your goal would be to combine the iterator plugin with a copy resource and filter enabled. You could even add custom properties file to use as a filter in case you have other attributes that are unique per node with this approach.
If there are a lot of target configurations that need to be copied, you could use the maven-antrun-plugin together with ant macrodef.
If you really have a lot of target configurations, you could also use ant-contrib to iterate over a list of target configurations.
There's an example how to do this here
You could indeed use
resources:copy-resources
and several<execution>
in your POM (note thatresources:copy-resources
doesn't allow to change the name of the target file though).Let's assume you have the following structure:
Where
log4j.properties
is using place holders and thefilter-nodeN.properties
files contain the values. For example:Then, in your
pom.xml
, configure the resources plugin and define one<execution>
per node to callcopy-resources
with a specific output directory and a specific filter to use:Running mvn
process-resources
would produce the following result:With the appropriate values in each
log4j.properties
.This kinda works, but is verbose and this might be a problem if you have a decent amount of nodes.
I tried to write something more concise and maintainable using the Maven AntRun Plugin but I couldn't get the.for
task fromant-contrib
to work under Maven (for an unknown reason, thefor
task isn't recognized) and I gave upHere is an alternative using the Maven AntRun Plugin. Nothing complicated, no loop, I'm just copying the source file to another location, changing its name on the fly and filtering the content:
Note that Ant uses
@
by default as delimiters for token (couldn't get it to use maven style delimiters) so thelog4j.properties
became:But, since these values seem to be node specific, did you consider using system properties instead (that you could place in the startup scripts)? This is something I've already done (with a
log4j.xml
), it works well and it would highly simplify things.