【问题标题】:Spring Logging SLF4J binded to Log4JSpring Logging SLF4J 绑定到 Log4J
【发布时间】:2015-04-30 14:25:11
【问题描述】:

我正在尝试将我的 SpringMVC 应用程序配置为使用 SLF4J 而不是 vanilla commons-logging 进行日志记录。

我完全被卡住了,我的文件没有记录任何内容,尽管如果我调试代码,表达式 if (log.isDebugEnabled()) { 被评估为 true。

我做错了什么?

这是我的配置:

我的 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 类:

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

提前致谢, 迭戈。

【问题讨论】:

    标签: spring logging log4j slf4j


    【解决方案1】:

    您是否检查过任何 SLF4J 输出?如果存在多个 SLF4J 绑定,SLF4J 会抱怨它。

    另一个问题是;您已将记录器类别es.jumtech.workcontrol 设置为级别ALL,这会导致isDebugEnabled() 返回true。您应该至少可以在其中看到一些内容(如果您记录的大小超过 8k,这是默认缓冲区大小)。

    我提出三件事:

    1. 将根记录器临时设置为ALLDEBUG
    2. 使用 -Dlog4j.debug=true 启动您的应用程序。您应该会看到引导 log4j 的一些详细信息。
    3. 确保 logger.getClass().getName() 是 org.slf4j.impl.Log4jLoggerAdapter

    HTH,马克

    【讨论】:

    • 谢谢@mp911de 你是对的!!! “logger”是 ch.qos.logback.classic.Logger 的实例,而不是 org.slf4j.impl.Log4jLoggerAdapter,另一个依赖项是导入 logback 库。
    【解决方案2】:

    这是我通常选择的设置。在我的 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);
    

    【讨论】:

    • 除了 log4j 的配置方式似乎都一样,对吧?顺便说一句,我已将 log4j.xml 更改为 log4j.properties 样式,但没有任何改变。
    • 在你的maven依赖中,摆脱你的排除,jcl over slf4j和log4j
    猜你喜欢
    • 2014-10-31
    • 2023-03-18
    • 2013-10-01
    • 2013-09-29
    • 1970-01-01
    • 2015-05-28
    • 2011-03-03
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多