当前位置: 首页 > 知识库问答 >
问题:

如何在Hibernate 4中配置日志以使用SLF4J

马晓博
2023-03-14

Hibernate 3. x使用slf4j进行日志记录。Hibernate 4. x使用jboss日志记录。我正在编写一个使用Hibernate 4和SLF4J进行日志记录的独立应用程序。

如何配置Hibernate以登录到SLF4J?

如果这不可能,我如何配置Hibernate的日志记录?

Hibernate 4.1关于日志记录的手动部分以警告开始,它是。。。

完全过时了。Hibernate从4.0开始使用JBoss日志记录。这将在我们将此内容迁移到《开发人员指南》时得到记录。

...继续谈论SLF4J,所以毫无用处。入门指南和开发人员指南都没有谈论日志记录。迁移指南也没有。

我已经在jboss日志记录本身寻找留档,但我根本找不到任何。GitHub页面是静默的,JBoss的社区项目页面甚至没有列出jboss日志记录。我想知道这个项目的错误跟踪器是否可能存在与提供留档相关的任何问题,但它没有。

好消息是,当在应用程序服务器(例如JBoss AS7)中使用Hibernate 4时,日志记录在很大程度上是为您处理的。但是我如何在独立应用程序中配置它呢?

共有3个答案

华良平
2023-03-14

受Leif的Hypoport帖子的启发,这就是我如何将Hibernate 4“弯曲”回slf4j:

假设您使用的是Maven。

  • 添加组织。slf4j:log4j-over-slf4j作为pom的依赖项。xml

背景:Hibernate 4. x依赖于工件org.jboss.logging: jboss日志记录。暂时地,这个工件对工件slf4j: slf4j有一个提供的范围依赖。

正如我们现在添加的组织。slf4j:log4j-over-slf4jartifact,org。slf4j:log4j-over-slf4j模拟slf4j:slf4j工件。因此,JBoss日志记录的所有内容现在实际上都将通过slf4j进行。

假设您使用Logback作为日志后端。这是一个示例pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    ....
    <properties>
        ....
        <slf4j-api-version>1.7.2</slf4j-api-version>
        <log4j-over-slf4j-version>1.7.2</log4j-over-slf4j-version>
        <jcl-over-slf4j-version>1.7.2</jcl-over-slf4j-version> <!-- no problem to have yet another slf4j bridge -->
        <logback-core-version>1.0.7</logback-core-version>
        <logback-classic-version>1.0.7</logback-classic-version>
        <hibernate-entitymanager-version>4.1.7.Final</hibernate-entitymanager-version> <!-- our logging problem child -->
    </properties>

    <dependencies>
            <!-- begin: logging-related artifacts .... -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j-api-version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>${jcl-over-slf4j-version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>log4j-over-slf4j</artifactId>
                <version>${log4j-over-slf4j-version}</version>
            </dependency>   
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>${logback-core-version}</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>${logback-classic-version}</version>
            </dependency>
            <!-- end: logging-related artifacts .... -->

            <!-- begin: some artifact with direct dependency on log4j:log4j ....  -->
            <dependency>
            <groupId>org.foo</groupId>
                <artifactId>some-artifact-with-compile-or-runtime-scope-dependency-on-log4j:log4j</artifactId>
                <version>${bla}</version>
                <exclusions>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>   
            </dependency>
            <!-- begin: some artifact with direct dependency on log4j:log4j ....  -->

            <!-- begin: a hibernate 4.x problem child........... -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>${hibernate-entitymanager-version}</version>
            </dependencies>
            <!-- end: a hibernate 4.x problem child........... -->
    ....
</project>

在类路径上,有一个logback.xml,例如位于src/main/java中的这个:

<!-- begin: logback.xml -->
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender> 

<logger name="org.hibernate" level="debug"/>

<root level="info">
    <appender-ref ref="console"/>
</root>

</configuration>
<!-- end: logback.xml -->

某些组件可能希望在JVM启动时访问logback.xml以进行正确的日志记录,例如Jetty Maven插件。在这种情况下,将Javasystemlogback.configurationFile=./path/to/logback.xml添加到您的命令中(例如mvn-Dlogback.configurationFile=./目标/类/logback.xmljetty: run)。

如果您仍然获得“原始”控制台标准输出Hibernate(如Hibernate:选择…),那么堆栈溢出问题“关闭控制台的Hibernate日志记录”可能适用。

秋博容
2023-03-14
匿名用户

要让SLF4J在没有Logback作为后端的情况下使用JBoss Logging,需要使用系统属性org.jboss.logging.provider=slf4jlog4j-over-slf4j策略在这种情况下似乎不起作用,因为如果Logback和log4j实际上都不存在于类路径中,日志记录将回退到JDK。

这有点麻烦,为了让自动检测工作起来,您已经看到类加载器至少包含了ch.qos。返回日志。经典logback classic或org的记录器。阿帕奇。log4j。log4j中的层次结构(Hierarchy),欺骗JBoss日志记录不返回JDK日志记录。

魔法在org.jboss.logging.LoggerProviders中解释

更新:添加了服务加载器支持,因此可以通过声明META-INF/service/org.jboss.logging.LoggerProvider(使用org.jboss.logging.Slf4jLoggerProvider作为值)来避免自动检测问题。似乎也添加了支持log4j2。

任小云
2023-03-14

关注https://github.com/jboss-logging/jboss-logging/blob/master/src/main/java/org/jboss/logging/LoggerProviders.java:

static final String LOGGING_PROVIDER_KEY = "org.jboss.logging.provider";

private static LoggerProvider findProvider() {
    // Since the impl classes refer to the back-end frameworks directly, if this classloader can't find the target
    // log classes, then it doesn't really matter if they're possibly available from the TCCL because we won't be
    // able to find it anyway
    final ClassLoader cl = LoggerProviders.class.getClassLoader();
    try {
        // Check the system property
        final String loggerProvider = AccessController.doPrivileged(new PrivilegedAction<String>() {
            public String run() {
                return System.getProperty(LOGGING_PROVIDER_KEY);
            }
        });
        if (loggerProvider != null) {
            if ("jboss".equalsIgnoreCase(loggerProvider)) {
                return tryJBossLogManager(cl);
            } else if ("jdk".equalsIgnoreCase(loggerProvider)) {
                return tryJDK();
            } else if ("log4j".equalsIgnoreCase(loggerProvider)) {
                return tryLog4j(cl);
            } else if ("slf4j".equalsIgnoreCase(loggerProvider)) {
                return trySlf4j();
            }
        }
    } catch (Throwable t) {
    }
    try {
        return tryJBossLogManager(cl);
    } catch (Throwable t) {
        // nope...
    }
    try {
        return tryLog4j(cl);
    } catch (Throwable t) {
        // nope...
    }
    try {
        // only use slf4j if Logback is in use
        Class.forName("ch.qos.logback.classic.Logger", false, cl);
        return trySlf4j();
    } catch (Throwable t) {
        // nope...
    }
    return tryJDK();
}

因此,org.jboss.logging.provider的可能值是:jbossjdklog4jslf4j

如果您没有设置org.jboss.logging.provider,它会尝试jboss,然后log4j,然后slf4j(仅当使用logback时)并回退到jdk。

我将slf4j与logback classic一起使用:

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.13</version>
        <scope>${logging.scope}</scope>
    </dependency>

和所有工作正常!

更新一些用户使用非常主要的pp.java:

static { //runs when the main class is loaded.
    System.setProperty("org.jboss.logging.provider", "slf4j");
}

但是对于基于容器的解决方案,这是行不通的。

更新2那些认为自己使用SLF4J管理jboss日志的人,事实并非如此jboss日志记录直接使用Log4j而不使用SLF4J!

 类似资料:
  • 我最近切换到ApacheLog4J2,仍然找不到使用log4j2配置hibernate日志的方法。xml。 因为我找不到解决这个问题的方法,我仍然使用log4j.properties文件显式Hibernate。这不是最好的解决方案,因为我的log4j2.xml使用JPA appender(将日志写入数据库)。我不想为Hibernate编写单独的逻辑。 有没有办法使用log4j2配置Hibernat

  • 问题内容: 除了将日志记录级别设置为,我想使用默认的SLF4J + Logback配置。 我该如何使用Java代码呢? 我没有使用XML,而是在运行时做出此决定。 问题答案: 以下内容对我有用,但通常这不是一个好主意。您的代码将取决于Logback(您不能在SLF4J之后选择另一个日志框架)。

  • 在jboss中配置日志记录的最佳方法是什么,我已经尝试了2种方法(都失败了):1.)使用jboss内置,根据一些文章我只需要添加对slf4j-api的依赖,就像提供的范围: *这里的问题是在eclipse控制台中没有显示日志。 2.)使用logback,所以我在jboss-deployment-structure.xml中排除了slf4j和impl,并且在我的war项目中包含了slf4j/logb

  • 使用java.util.Logging时,可以在logging.properties文件中配置特定类的日志级别(即具有类名称的子记录器),如下所示: 我使用类名在MyClass中创建子记录器,如下所示: 在Google Web Toolkit gwt.xml文件中有类似的配置方法吗?

  • 我有一个在Kubernetes pod中运行的应用程序Java/Spring boot,日志配置为stdout,fluentd从默认路径获取日志: 在我的logback xml配置中,我有一个appender json文件: 如何在Kubernete设置中集成这个独立的日志文件,而不是stdout和Fluentd,以不同的路径发送json日志

  • 在像这样的典型Spring Boot应用程序中,我们如何配置它来使用“自定义”日志配置? 例如,在我的应用程序运行的当前环境中,日志正在导致错误,我如何使用其他日志例如: