Logback+SLF4J 不登录 JavaEE 7 应用程序
Logback+SLF4J does no log in JavaEE 7 application
我正在构建一个简单的应用程序,现在我在 javaee 应用程序上遇到 "logging nightmare"。我已经进行了数天的搜索,数百次 change/test,但没有办法做到 运行。
我的应用程序由一个简单的
EAR
+-- /lib
| +-- slf4j-api-1.7.25.jar
| +-- logback-classic-1.2.3.jar
| +-- logback-core-1.2.3.jar
|
+-- JAR (JPA/EJB/Producers/Interceptors)
| +--src/main/resources
| +-- logback.xml
| +-- logback-test.xml
|
+-- WAR
EAR 文件的 lib 目录中的库就是这样加载的。
我的 EJB 项目中的 pom.xml 包含以下依赖项:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
还有 javaee-api-7.0 提供。
我将日志工具放在 EJB 项目中,这样我就可以在 web 应用程序中使用日志生成器,并将记录器也注入到 JSF 控制器中。
logback.xml 是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<property name="DEV_HOME" value="c:/Dev" />
<appender name="FILE-AUDIT"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/debug.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>WE:%d{yyyy-MM-dd HH:mm:ss} - %msg%n</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/archived/debug.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="it.univaq.we2018" level="DEBUG" additivity="false">
<appender-ref ref="FILE-AUDIT" />
</logger>
<root level="ERROR">
<appender-ref ref="FILE-AUDIT" />
</root>
</configuration>
我所有的类都在it.univaq.we2018包下(.service, .controllers, ....)。
这是 CDI 生产者(System.out 只是为了我的目的):
@Named
@Singleton
public class LoggerProducer {
@Produces
public Logger produceLogger(InjectionPoint ip) {
System.out.println("-----> construct logging for: "+ip.getMember().getDeclaringClass());
Logger log = LoggerFactory.getLogger(ip.getMember().getDeclaringClass());
System.out.println("-----> LogFactory is: "+log+" for "+log.getName());
return log;
}
}
这是一个使用它的 EJB:
@Stateless
@LocalBean
public class SecurityService implements Serializable {
@Inject
Logger log;
public boolean performSecurityCheck(String userName, String target) {
log.debug("Testing ["+target+"] for user ["+userName+"]...");
return true;
}
}
Logger和LoggerFactory的包是org.slf4j
尝试将 logback.xml 移动到每个 folder/package 下...什么都没有。输出始终相同:
INFORMAZIONI: indexController.init() INFORMAZIONI: ---- ENTER:
[it.univaq.we2018.tutor.controller.IndexController.doAction()]
INFORMAZIONI: -----> construct logging for: class
it.univaq.we2018.tutor.service.SecurityService
INFORMAZIONI: -----> LogFactory is:
Logger[it.univaq.we2018.tutor.service.SecurityService]
for it.univaq.we2018.tutor.service.SecurityService
INFORMAZIONI: 10:38:34.423 [http-thread-pool::http-listener-1(4)] DEBUG
it.univaq.we2018.tutor.service.SecurityService - Testing
[it.univaq.we2018.tutor.controller.IndexController.doAction()] for
user [null]...
INFORMAZIONI: indexController.doAction() INFORMAZIONI:
BaseService.businessMethod() INFORMAZIONI: ---- EXIT:
[it.univaq.we2018.tutor.controller.IndexController.doAction()]
日志行 #4 是应该转到文件的行,但文件从未打开,日志格式与配置不一致(应以 WE: 前缀并有不同的模式)。
我不知道如何解决这个问题。我一直认为 JavaEE 应用程序的日志记录需要从头开始进行彻底的重新设计:appserver 应该提供一个 "plugin" 机制,就像数据源一样,减少与配置、类加载相关的所有问题,库冲突等等。
运行 在 NetBeans 8.2 maven javaee7 原型项目上,Java 1.8_172 在 Payara 5.182 下。
您遇到资源可见性问题。
EAR/lib 目录中的 Jar 看不到 类 或 EJB jar 或 WAR 文件中的资源。您的配置当前似乎位于 EJB 模块中。因此 EAR/lib 目录中的 log-back 类 看不到配置文件。
如果您必须打包日志记录配置,那么它需要放在 EAR/lib 目录中的 jar 中才能找到它。
有关 EAR 文件中资源可见性和 类 的更多信息,请参阅我对 的回答。
就个人而言,我更喜欢外部化日志记录配置。在 log-back 的情况下,您可以使用 -Dlogback.configurationFile=/path/to/config.xml
环境变量指定配置文件的路径。
我正在构建一个简单的应用程序,现在我在 javaee 应用程序上遇到 "logging nightmare"。我已经进行了数天的搜索,数百次 change/test,但没有办法做到 运行。 我的应用程序由一个简单的
EAR
+-- /lib
| +-- slf4j-api-1.7.25.jar
| +-- logback-classic-1.2.3.jar
| +-- logback-core-1.2.3.jar
|
+-- JAR (JPA/EJB/Producers/Interceptors)
| +--src/main/resources
| +-- logback.xml
| +-- logback-test.xml
|
+-- WAR
EAR 文件的 lib 目录中的库就是这样加载的。
我的 EJB 项目中的 pom.xml 包含以下依赖项:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
还有 javaee-api-7.0 提供。 我将日志工具放在 EJB 项目中,这样我就可以在 web 应用程序中使用日志生成器,并将记录器也注入到 JSF 控制器中。 logback.xml 是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<property name="DEV_HOME" value="c:/Dev" />
<appender name="FILE-AUDIT"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/debug.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>WE:%d{yyyy-MM-dd HH:mm:ss} - %msg%n</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/archived/debug.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="it.univaq.we2018" level="DEBUG" additivity="false">
<appender-ref ref="FILE-AUDIT" />
</logger>
<root level="ERROR">
<appender-ref ref="FILE-AUDIT" />
</root>
</configuration>
我所有的类都在it.univaq.we2018包下(.service, .controllers, ....)。 这是 CDI 生产者(System.out 只是为了我的目的):
@Named
@Singleton
public class LoggerProducer {
@Produces
public Logger produceLogger(InjectionPoint ip) {
System.out.println("-----> construct logging for: "+ip.getMember().getDeclaringClass());
Logger log = LoggerFactory.getLogger(ip.getMember().getDeclaringClass());
System.out.println("-----> LogFactory is: "+log+" for "+log.getName());
return log;
}
}
这是一个使用它的 EJB:
@Stateless
@LocalBean
public class SecurityService implements Serializable {
@Inject
Logger log;
public boolean performSecurityCheck(String userName, String target) {
log.debug("Testing ["+target+"] for user ["+userName+"]...");
return true;
}
}
Logger和LoggerFactory的包是org.slf4j
尝试将 logback.xml 移动到每个 folder/package 下...什么都没有。输出始终相同:
INFORMAZIONI: indexController.init() INFORMAZIONI: ---- ENTER:
[it.univaq.we2018.tutor.controller.IndexController.doAction()]
INFORMAZIONI: -----> construct logging for: class
it.univaq.we2018.tutor.service.SecurityService
INFORMAZIONI: -----> LogFactory is:
Logger[it.univaq.we2018.tutor.service.SecurityService]
for it.univaq.we2018.tutor.service.SecurityService
INFORMAZIONI: 10:38:34.423 [http-thread-pool::http-listener-1(4)] DEBUG
it.univaq.we2018.tutor.service.SecurityService - Testing
[it.univaq.we2018.tutor.controller.IndexController.doAction()] for
user [null]...
INFORMAZIONI: indexController.doAction() INFORMAZIONI:
BaseService.businessMethod() INFORMAZIONI: ---- EXIT:
[it.univaq.we2018.tutor.controller.IndexController.doAction()]
日志行 #4 是应该转到文件的行,但文件从未打开,日志格式与配置不一致(应以 WE: 前缀并有不同的模式)。 我不知道如何解决这个问题。我一直认为 JavaEE 应用程序的日志记录需要从头开始进行彻底的重新设计:appserver 应该提供一个 "plugin" 机制,就像数据源一样,减少与配置、类加载相关的所有问题,库冲突等等。
运行 在 NetBeans 8.2 maven javaee7 原型项目上,Java 1.8_172 在 Payara 5.182 下。
您遇到资源可见性问题。
EAR/lib 目录中的 Jar 看不到 类 或 EJB jar 或 WAR 文件中的资源。您的配置当前似乎位于 EJB 模块中。因此 EAR/lib 目录中的 log-back 类 看不到配置文件。
如果您必须打包日志记录配置,那么它需要放在 EAR/lib 目录中的 jar 中才能找到它。
有关 EAR 文件中资源可见性和 类 的更多信息,请参阅我对
就个人而言,我更喜欢外部化日志记录配置。在 log-back 的情况下,您可以使用 -Dlogback.configurationFile=/path/to/config.xml
环境变量指定配置文件的路径。