Let assume I have a jar file called myApp.jar. The jar file is a comprised of 4 applications. All four applications within the jar file use the same code within the jar file and the only difference is how data is extracted and transformed. The packages within the jar file look something like this
com.myapp
|-App1Main.java
|-App2Main.java
|-App3Main.java
|-App4Main.java
com.myapp.transform
|-App1Transform
|-App2Transform
|-App3Transform
com.myapp.service
|-MyAppService.java
com.myapp.model
|-{ModelClasses}
com.myapp.dao
|-MyAppDAO
The only difference is that each application uses a different set of algrithms to transform/convert data from different sources. Once the data is converted, the service, dao, model classes are all shared between the different applications. The applications are run using a command similar to this one
$JAVA_HOME/java -cp myApp.jar com.myApp.App1Main.java
The jar file contains a log4j.propeties file that is used by all three applications.
log4j.rootLogger=WARN, stdout, myAppLogger
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.myAppLogger.File=/myapp/logs/myapp.log
log4j.appender.myAppLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.myAppLogger.DatePattern=.dd-MM-yyyy
log4j.appender.myAppLogger.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.appender.myAppLogger=org.apache.log4j.DailyRollingFileAppender
At the moment, the above configuration means that each of the 3 applications within the jar file all write to the same log file - i.e. /myapp/logs/myapp.log I would like to change this so that each application writes to its own log file.
One solution i have found is to change the log file configuration to this:
log4j.appender.myAppLogger.File=/myapp/logs/${logfile.name}
Then just call each application using a different logfile name as a system property as shown below:
$JAVA_HOME/java -cp myApp.jar com.myApp.App1Main.java -Dlogfile.name=myApp1Log.log
$JAVA_HOME/java -cp myApp.jar com.myApp.App1Main.java -Dlogfile.name=myApp2Log.log
$JAVA_HOME/java -cp myApp.jar com.myApp.App1Main.java -Dlogfile.name=myApp3Log.log
$JAVA_HOME/java -cp myApp.jar com.myApp.App1Main.java -Dlogfile.name=myApp4Log.log
The above will probably work but i am not so keen on using system properties. Is there a way of achieving the same thing using multiple loggers?
I know that i can setup up multiple loggers and call the relevant logger within the application but the issue i have is i have no way of knowing which application is currently running on some of the classes. For example..
Setup multiple loggers
log4j.rootLogger=WARN, stdout,MyApp1, MyApp2, MyApp3, MyApp4
# setup MyApp1
log4j.appender.myAppLogger=org.apache.log4j.RollingFileAppender
log4j.appender.myAppLogger.File=/myapp/logs/myapp1.log
...
...
# setup MyApp4
log4j.appender.LoudAppender=org.apache.log4j.RollingFileAppender
log4j.appender.myAppLogger.File=/myapp/logs/myapp4.log
...
log4j.logger.com.yourpackage.yourclazz=TRACE
the MyAppService and MyAppDAO classes are used by all 4 applications. If i want to write to the log file while in MyAppService or MyAppDAO i will have to do something like:
- import all 4 loggers in MyAppservice
- if the application is myapp1 use myapp1 logger
- if the application is myapp2 use myapp2 logger
- if the application is myapp3 use myapp3 logger
- if the application is myapp4 use myapp4 logger
The above will also probably work but having multiple if statements in several places within the code is not very clean.
I am looking for a better cleaner more generic approach that does not require having IF statements or passing around the name of the application within methods etc. Any better suggestions?