views:

30

answers:

3

I have a project where I create a JAR which contains a bunch of classes with main() plus a set of scripts which set the environment to invoke them. Most of those are long running processes which log a lot (~10-20GB).

This means I have a pretty complex log4j.xml file which, being in src/main/resources/, goes into the JAR. When something breaks in the production system, I'd like to modify the logging on the fly for a single run.

So I came up with the idea to have a conf/ directory on the production and put that into the classpath, first. Then, I thought that it would be great if M2 would put the config files in there (instead of the JAR). But that would overwrite any manual changes during an automated deployment which I strongly dislike. I'm also not fond of timestamps and things like that.

So my next ideas was this: M2 should leave the config files in the JAR but create copies of the files with the name *.tpl in the conf/ directory. The admin could then copy a template to the basename to override the files in the JARs. .tpl-Files would be overwritten but that wouldn't hurt. Admins would have full control over which version of the log was active and they could run a diff to see whether any important changes were made.

Now the question: Has someone seen a plugin which automates this process? That is which creates a conf/ directory with all or a selected subset of everything in src/main/resources/ and which renames the files?

A: 

I may be missing something and this doesn't answer directly the question but did you consider producing a zip assembly of the exploded content of required artifacts (to be unzipped on the target environment)?

Pascal Thivent
I could do that but it would drown the admins in a really big heap of files. I'd prefer something which just contains a the few files where it makes sense to change something after deployment. Also, this solution would overwrite any manual changes on any subsequent deployment.
Aaron Digulla
A: 

Sounds like you're attacking the problem the wrong way. Why not just run the application with -Dlog4j.configuration=/some/where/my-log4j.properties? If you want, you can add a command line flag to main() which invokes the PropertyConfigurator directly.

Dominic Mitchell
Because I'm also generating the start scripts, so this change would also be overwritten. I'm looking for something which doesn't get into the way of automatic deployment.
Aaron Digulla
But can you not allow for this in the startup scripts?
Dominic Mitchell
That still doesn't give them a template of the config file to start with when they need to make changes. They'd have to unpack the JAR, find the files, copy them around. I don't like it :/
Aaron Digulla
+1  A: 
  • Best practice in Maven handling config files is to place them in a separate conf directory, and pack them in a binary assembly using the assembly plugin. Placing configuration files, like log4j.xml in the src/main/resources doesn't make sense, since it is not a true application resource, but more of a configuration file.

  • We cope with the overwriting, by packing the configuration files with the posfix .def. For example: myapp.properties is packed into the assembly as myapp.properties.def. When the person who uses the assembly unpacks it, it will not overwrite his original files. After unpacking he simply merges them by an external tool (we use meld in Fedora Core).

Asaf Mesika
Sounds interesting. How do you make log4j pick up the file when it's not on the classpath? For example, when you run the app in your IDE?
Aaron Digulla
Normally you have log4j.xml file specific for testing purposes. If you want to use the conf file in testing, then you should define conf directory as a resource directory in maven, and exclude it when building the jar, but I believe a specific log4j.xml located in src/test/resources is better
Asaf Mesika