log4j - 写入/记录到多个日志文件取决于应用程序

时间:2013-04-12 13:58:51

标签: java logging log4j

假设我有一个名为myApp.jar的jar文件。 jar文件由4个应用程序组成。 jar文件中的所有四个应用程序在jar文件中使用相同的代码,唯一的区别是如何提取和转换数据。 jar文件中的包看起来像这样

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

唯一的区别是每个应用程序使用一组不同的算法来转换/转换来自不同来源的数据。转换数据后,服务,dao,模型类都在不同的应用程序之间共享。应用程序使用类似于此命令的命令运行

$JAVA_HOME/java -cp myApp.jar com.myApp.App1Main.java

jar文件包含一个由所有三个应用程序使用的log4j.propeties文件。

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

目前,上述配置意味着jar文件中的3个应用程序中的每个应用程序都写入相同的日志文件 - 即/myapp/logs/myapp.log 我想改变它,以便每个应用程序写入自己的日志文件。

我发现的一个解决方案是将日志文件配置更改为:

log4j.appender.myAppLogger.File=/myapp/logs/${logfile.name}

然后使用不同的日志文件名称作为系统属性调用每个应用程序,如下所示:

$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

以上可能会有效,但我不太热衷于使用系统属性。有没有办法使用多个记录器实现相同的功能?

我知道我可以设置多个记录器并在应用程序中调用相关的记录器,但我遇到的问题是我无法知道哪个应用程序 目前正在运行某些类。例如..

设置多个记录器

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

所有4个应用程序都使用MyAppService和MyAppDAO类。如果我想写信给 在MyAppService或MyAppDAO中的日志文件我必须执行以下操作:

- 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

上面也可能有用但在代码中的几个地方有多个if语句并不是很干净。

我正在寻找一种更清洁,更通用的方法,它不需要使用IF语句或在方法中传递应用程序的名称等。 还有更好的建议吗?

2 个答案:

答案 0 :(得分:2)

您希望每个类都登录到同一个文件,但文件名应取决于入口点。在每个Main类中,您可以:

  • 以编程方式设置并将appender添加到根记录器。
  • 或加载其他属性文件
  • 或设置包含文件名的系统属性(而不是在命令行上设置)

答案 1 :(得分:1)

我喜欢使用多个记录器的想法。正如我所看到的那样,在MyAppService和MyAppDAO类等常用类中使用记录器存在问题。我会说在实例化这些对象时,将logger对象传递给构造函数。如果使用静态记录器对象,那么您可能希望将参数传递给调用这些对象的方法。这样您就不需要对记录器进行if-else条件检查。