我有一个大型应用程序在JBoss 5.1上运行,并通过slf4j使用log4j。当我在本地docker容器中测试时,我可以在日志中看到常见的package.class名称:
03 Dec 15 09:45:39, DEBUG my.fancy.app.filters.TicketValidationFilter:doFilter:30 Ticket was verified with data: uniqueID=gfd, idnumber=sdf, mid=11246986.
03 Dec 15 09:45:39, DEBUG my.fancy.app.MyServlet:doGet:30 Request for secret data with uniqueId=gfd
03 Dec 15 09:45:39, WARN my.fancy.app.MyServlet:doGet:36 Could not retrieve SecretData with uniqueId=gfd
然而,当我将相同的代码部署到开发环境(可能没有那么干净…)时,我得到:
03 dec 15 10:45:22, DEBUG org.jboss.logging.Logger:debug:228 Ticket was verified with data: uniqueID=sdg, idnumber=sdf, mid=11738149.
03 dec 15 10:45:22, DEBUG org.jboss.logging.Logger:debug:228 Request for secret data with uniqueId=sdg
03 dec 15 10:45:22, WARN org.jboss.logging.Logger:warn:352 Could not retrieve SecretData with uniqueId=sdg
我比较了两种环境中的jboss-log4j.xml,发现它们是相同的。我还检查了启动标志,看看是否设置了日志记录提供程序,但它不在这两种环境中。
我下一步该去哪里?
更新
我还应该提到,以前我们一直直接使用log4j,所以我们仍然有分散在各处的直接log4j导入和实例化。奇怪的是,那些使用log4j记录的条目在所有环境中都能正确显示,而那些使用slf4j的条目只在某些环境中显示。这应该是一个线索,表明slf4j在有问题的环境中没有真正正确配置。问题是我应该在哪里修复它?
更新2
这是附加程序配置:
<appender name="MYAPP_FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
<param name="File" value="${jboss.server.log.dir}/myapp.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{dd MMM yyy HH:mm:ss}, %-6p %C:%M:%L %m %n" />
</layout>
</appender>
记录器解密:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
public class MyServlet extends HttpServlet {
private Logger log = LoggerFactory.getLogger(MyServlet.class.getName());
...
log.debug("Request for secret data with uniqueId={}", secretDataVO.getUniqueId());
...
}
在pom.xml中,我有:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.10</version>
<scope>provided</scope>
</dependency>
对log4j的依赖是存在的,因为在应用程序代码的其他地方,我们仍然直接使用log4j。slf4j-log4j12被标记为已提供,因为它是由同一jboss实例中的另一个工件加载的。
更新3
启动jboss:时显示错误
2015-12-07 16:16:50,127 ERROR [STDERR] log4j:ERROR A "org.jboss.logging.appender.FileAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
2015-12-07 16:16:50,127 ERROR [STDERR] log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
2015-12-07 16:16:50,127 ERROR [STDERR] log4j:ERROR [BaseClassLoader@14a33aa{vfszip:/my-jboss-root/jboss/server/default/deploy/fancyApp.ear/fancyApp-web.war/}] whereas object of type
2015-12-07 16:16:50,127 ERROR [STDERR] log4j:ERROR "org.jboss.logging.appender.FileAppender" was loaded by [org.jboss.bootstrap.NoAnnotationURLClassLoader@15b0afd].
2015-12-07 16:16:50,127 ERROR [STDERR] log4j:ERROR Could not instantiate appender named "FILE".
其中fancyApp-web.war是加载slf4j-log4j12的一个。我以前看到过这个错误,但没有提到它,因为它出现在本地(docker)和开发环境中(甚至在prod中…)
尝试使用LoggerFactory.getLogger(MyServlet.class)
,如下所述:http://www.slf4j.org/api/org/slf4j/LoggerFactory.html#getLogger%28java.lang.Class%29
如果clazz参数与调用者的名称不同由SLF4J内部计算,将显示记录器名称不匹配警告打印,但仅当slf4j.detectLoggerNameMismatch系统属性设置为true。默认情况下,未设置此属性并且没有警告即使在记录器名称不匹配的情况下也会打印。
还要在log4j.xml中设置debug="true"
,并观察log4j的初始化情况。
在配置文件中为生产环境设置调试器true。