Spring 记录绑定到 Log4J 的 SLF4J
Spring Logging SLF4J binded to Log4J
我正在尝试将我的 SpringMVC 应用程序配置为使用 SLF4J 而不是 vanilla commons-logging 进行记录。
我完全卡住了,我的文件没有记录任何内容,尽管如果我调试代码,表达式 if (log.isDebugEnabled()) {
的计算结果为真。
我做错了什么?
这是我的配置:
我的pom.xml
<!-- Logging -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>runtime</scope>
</dependency>
我的log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<appender name="fileAppender" class="org.apache.log4j.FileAppender">
<param name="Threshold" value="ALL" />
<param name="File" value="${catalina.home}/logs/workcontrol.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="es.jumtech.workcontrol">
<level value="ALL" />
<appender-ref ref="fileAppender" />
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="info" />
</logger>
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
<logger name="org.springframework.web">
<level value="info" />
</logger>
<logger name="org.hibernate">
<level value="info" />
</logger>
<!-- Root Logger -->
<root>
<priority value="ERROR" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
我的 Java Class 应该记录:
package es.jumtech.workcontrol.persistence.initial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import es.jumtech.workcontrol.persistence.dao.ProfileDAO;
import es.jumtech.workcontrol.persistence.dao.RoleDAO;
import es.jumtech.workcontrol.persistence.entity.Profile;
import es.jumtech.workcontrol.persistence.entity.Role;
@Component
public class DataSeeder implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private RoleDAO roleDAO;
@Autowired
private ProfileDAO profileDAO;
private static final Logger log = LoggerFactory.getLogger(DataSeeder.class);
@Override
@Transactional(readOnly = false)
public void onApplicationEvent(ContextRefreshedEvent event) {
// Se inicializan los roles
loadRoles();
// Se inicializan los perfiles
loadProfiles();
}
private void loadRoles() {
if (log.isDebugEnabled()) {
log.debug("Se comprueba si existen los roles");
}
Role roleBoss = roleDAO.getRoleByName(Role.BOSS);
if (roleBoss == null) {
log.error("No existe el rol ROLE_BOSS, se crea");
roleBoss = new Role();
roleBoss.setRole(Role.BOSS);
roleDAO.createRole(roleBoss);
}
Role roleAdmin = roleDAO.getRoleByName(Role.ADMIN);
if (roleAdmin == null) {
log.error("No existe el rol ROLE_ADMIN, se crea");
roleAdmin = new Role();
roleAdmin.setRole(Role.ADMIN);
roleDAO.createRole(roleAdmin);
}
Role roleWorker = roleDAO.getRoleByName(Role.WORKER);
if (roleWorker == null) {
log.error("No existe el rol ROLE_WORKER, se crea");
roleWorker = new Role();
roleWorker.setRole(Role.WORKER);
roleDAO.createRole(roleWorker);
}
}
private void loadProfiles() {
log.error("Se comprueba si existen los perfiles");
Profile deliveryProfile = profileDAO.getProfileByName("Repartidor");
if (deliveryProfile == null) {
log.error("No existe el perfil Repartidor, se crea");
deliveryProfile = new Profile();
deliveryProfile.setProfile("Repartidor");
profileDAO.createProfile(deliveryProfile);
}
Profile comercialProfile = profileDAO
.getProfileByName("Agente Comercial");
if (comercialProfile == null) {
log.error("No existe el perfil Agente Comercial, se crea");
comercialProfile = new Profile();
comercialProfile.setProfile("Agente Comercial");
profileDAO.createProfile(comercialProfile);
}
Profile officeProfile = profileDAO.getProfileByName("Oficinista");
if (officeProfile == null) {
log.error("No existe el perfil Oficinista, se crea");
officeProfile = new Profile();
officeProfile.setProfile("Oficinista");
profileDAO.createProfile(officeProfile);
}
}
}
解决方案
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
正如@mp911de 所指出的,此依赖项正在导入同样实现 SLFJ4 的 Logback 库,以及正在返回的记录器:
private static final Logger log = LoggerFactory.getLogger(DataSeeder.class);
是 ch.qos.logback.classic.Logger 的实例而不是 org.slf4j.impl.Log4jLoggerAdapter
提前致谢,
迭戈.
这是我通常使用的设置。在我的 Maven 项目中没有问题。
Maven 依赖项:
<!-- The slf4j api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<!-- The slf4j implementation -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
log4j.properties - 此文件应位于您的 src/main/resources 目录中:
# Root logger logging level option
log4j.rootLogger=ERROR, appenderName
# Redirect log messages to a log file
log4j.appender.appenderName=org.apache.log4j.RollingFileAppender
#outputs to Tomcat home
log4j.appender.appenderName.File=${catalina.home}/logs/MyLog.log
log4j.appender.appenderName.MaxFileSize=5MB
log4j.appender.appenderName.MaxBackupIndex=10
log4j.appender.appenderName.layout=org.apache.log4j.PatternLayout
log4j.appender.appenderName.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
在您的 java 代码中创建日志:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
当然,调用日志:
LOG.error("Some exception happened", exception);
您检查过任何 SLF4J 输出吗?如果存在 SLF4J 的多个绑定,SLF4J 会抱怨它。
另一个问题是;您已将记录器类别 es.jumtech.workcontrol
设置为级别 ALL
,这导致 isDebugEnabled()
为 return true。您至少应该在其中看到一些东西(以防您记录超过 8k,这是默认缓冲区大小)。
我提出三件事:
- 暂时将根记录器设置为
ALL
或DEBUG
- 使用 -Dlog4j.debug=true 启动您的应用程序。您应该看到引导 log4j 的一些细节。
- 确保 logger.getClass().getName() 是
org.slf4j.impl.Log4jLoggerAdapter
HTH,马克
我正在尝试将我的 SpringMVC 应用程序配置为使用 SLF4J 而不是 vanilla commons-logging 进行记录。
我完全卡住了,我的文件没有记录任何内容,尽管如果我调试代码,表达式 if (log.isDebugEnabled()) {
的计算结果为真。
我做错了什么?
这是我的配置:
我的pom.xml
<!-- Logging -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>runtime</scope>
</dependency>
我的log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<appender name="fileAppender" class="org.apache.log4j.FileAppender">
<param name="Threshold" value="ALL" />
<param name="File" value="${catalina.home}/logs/workcontrol.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="es.jumtech.workcontrol">
<level value="ALL" />
<appender-ref ref="fileAppender" />
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="info" />
</logger>
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
<logger name="org.springframework.web">
<level value="info" />
</logger>
<logger name="org.hibernate">
<level value="info" />
</logger>
<!-- Root Logger -->
<root>
<priority value="ERROR" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
我的 Java Class 应该记录:
package es.jumtech.workcontrol.persistence.initial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import es.jumtech.workcontrol.persistence.dao.ProfileDAO;
import es.jumtech.workcontrol.persistence.dao.RoleDAO;
import es.jumtech.workcontrol.persistence.entity.Profile;
import es.jumtech.workcontrol.persistence.entity.Role;
@Component
public class DataSeeder implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private RoleDAO roleDAO;
@Autowired
private ProfileDAO profileDAO;
private static final Logger log = LoggerFactory.getLogger(DataSeeder.class);
@Override
@Transactional(readOnly = false)
public void onApplicationEvent(ContextRefreshedEvent event) {
// Se inicializan los roles
loadRoles();
// Se inicializan los perfiles
loadProfiles();
}
private void loadRoles() {
if (log.isDebugEnabled()) {
log.debug("Se comprueba si existen los roles");
}
Role roleBoss = roleDAO.getRoleByName(Role.BOSS);
if (roleBoss == null) {
log.error("No existe el rol ROLE_BOSS, se crea");
roleBoss = new Role();
roleBoss.setRole(Role.BOSS);
roleDAO.createRole(roleBoss);
}
Role roleAdmin = roleDAO.getRoleByName(Role.ADMIN);
if (roleAdmin == null) {
log.error("No existe el rol ROLE_ADMIN, se crea");
roleAdmin = new Role();
roleAdmin.setRole(Role.ADMIN);
roleDAO.createRole(roleAdmin);
}
Role roleWorker = roleDAO.getRoleByName(Role.WORKER);
if (roleWorker == null) {
log.error("No existe el rol ROLE_WORKER, se crea");
roleWorker = new Role();
roleWorker.setRole(Role.WORKER);
roleDAO.createRole(roleWorker);
}
}
private void loadProfiles() {
log.error("Se comprueba si existen los perfiles");
Profile deliveryProfile = profileDAO.getProfileByName("Repartidor");
if (deliveryProfile == null) {
log.error("No existe el perfil Repartidor, se crea");
deliveryProfile = new Profile();
deliveryProfile.setProfile("Repartidor");
profileDAO.createProfile(deliveryProfile);
}
Profile comercialProfile = profileDAO
.getProfileByName("Agente Comercial");
if (comercialProfile == null) {
log.error("No existe el perfil Agente Comercial, se crea");
comercialProfile = new Profile();
comercialProfile.setProfile("Agente Comercial");
profileDAO.createProfile(comercialProfile);
}
Profile officeProfile = profileDAO.getProfileByName("Oficinista");
if (officeProfile == null) {
log.error("No existe el perfil Oficinista, se crea");
officeProfile = new Profile();
officeProfile.setProfile("Oficinista");
profileDAO.createProfile(officeProfile);
}
}
}
解决方案
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
正如@mp911de 所指出的,此依赖项正在导入同样实现 SLFJ4 的 Logback 库,以及正在返回的记录器:
private static final Logger log = LoggerFactory.getLogger(DataSeeder.class);
是 ch.qos.logback.classic.Logger 的实例而不是 org.slf4j.impl.Log4jLoggerAdapter
提前致谢, 迭戈.
这是我通常使用的设置。在我的 Maven 项目中没有问题。
Maven 依赖项:
<!-- The slf4j api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<!-- The slf4j implementation -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
log4j.properties - 此文件应位于您的 src/main/resources 目录中:
# Root logger logging level option
log4j.rootLogger=ERROR, appenderName
# Redirect log messages to a log file
log4j.appender.appenderName=org.apache.log4j.RollingFileAppender
#outputs to Tomcat home
log4j.appender.appenderName.File=${catalina.home}/logs/MyLog.log
log4j.appender.appenderName.MaxFileSize=5MB
log4j.appender.appenderName.MaxBackupIndex=10
log4j.appender.appenderName.layout=org.apache.log4j.PatternLayout
log4j.appender.appenderName.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
在您的 java 代码中创建日志:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
当然,调用日志:
LOG.error("Some exception happened", exception);
您检查过任何 SLF4J 输出吗?如果存在 SLF4J 的多个绑定,SLF4J 会抱怨它。
另一个问题是;您已将记录器类别 es.jumtech.workcontrol
设置为级别 ALL
,这导致 isDebugEnabled()
为 return true。您至少应该在其中看到一些东西(以防您记录超过 8k,这是默认缓冲区大小)。
我提出三件事:
- 暂时将根记录器设置为
ALL
或DEBUG
- 使用 -Dlog4j.debug=true 启动您的应用程序。您应该看到引导 log4j 的一些细节。
- 确保 logger.getClass().getName() 是
org.slf4j.impl.Log4jLoggerAdapter
HTH,马克