我的EAR结构如下:
APP.ear
- APP1.war
- WEB-INF/classes/log4j.properties
- APP2.war
- WEB-INF/classes/log4j.properties
- app1-ejb.jar
- app2-ejb.jar
- log4j.jar
- spring.jar
- commons-lang.jar (...and other jar)
我希望每个WAR都有自己的应用程序日志。但似乎上面的配置不起作用。 APP1和APP2的日志转到APP1的日志。无论如何要创建单独的应用程序日志吗?
答案 0 :(得分:8)
事实证明,由于类加载器,这是不可能的。类加载器层次结构如下:
应用程序类加载器 - > Ejb classloader - >战争类加载器
要获得单独战争的sepearte日志,可以将log4j.jar置于战争中,让log4j使用war类加载器。但由于app1-ejb.jar和app2-ebj.jar都需要使用log4j,因此log4j.jar只能放在顶层。所以log4j在应用程序类加载器级别上。
我可以指定一个log4j配置来将不同的包记录到不同的文件中。但对于像春天这样的公共图书馆,日志不能分开。
答案 1 :(得分:1)
因为log4j存在于根位置而无法工作的原因,而是让每个war在其WEB-INF / lib目录中都有一个Log4j.jar并从根目录中删除log4j.jar。
有关此内容的更多信息,请参阅我的博客文章 http://techcrawler.wordpress.com/
答案 2 :(得分:0)
您也可以使用代码中的PropertyConfigurator动态更改属性文件中的FILE属性。
答案 3 :(得分:0)
Logback是解决此问题的可行解决方案。在浏览了不同的hack以使用log4j后,我们决定切换到Logback。我在webapp中使用了Logback jar的以下配置。
webapp中的一个Logback文件,其中包含一个外部文件:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="10 seconds">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<contextName>${project.artifactId}</contextName>
<jmxConfigurator />
<include file="${logback.configuration.filepath}" />
</configuration>
在Maven过滤期间, ${logback.configuration.filepath}
将被配置文件的webapp外部的确切路径替换(类似于 /opt/server/conf/loback.included.conf )。
然后,logback.included.conf
的内容(此文件是项目的一部分,随build-helper:attach-artifact
一起提供,因此在{Maven过滤期间也会替换${project.artifactId}
):
<?xml version="1.0" encoding="UTF-8" ?>
<included>
<appender name="file" class="ch.qos.logback.core.FileAppender">
<file>/var/log/server/${project.artifactId}.log</file>
<encoder>
<pattern>[@/%contextName] %date{ISO8601} [%-5level] %thread:[%logger] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="file" />
</root>
</included>
仅限制,所包含文件的内容必须符合其中一个包含者。只是写规则。