118

Hibernate 3.x は、ロギングにを使用していました。Hibernate 4.x はを使用します。Hibernate 4 と SLF4J をログに使用するスタンドアロン アプリケーションを作成しています。

SLF4J にログを記録するように Hibernate を構成するにはどうすればよいですか?

それが不可能な場合、どうすれば Hibernate のログを構成できますか?

ロギングに関するHibernate 4.1のマニュアルセクションは、それが...

完全に古くなっています。Hibernate は 4.0 から JBoss Logging を使用します。これは、このコンテンツを開発者ガイドに移行する際に文書化されます。

... SLF4J について話し続けるので、役に立ちません。入門ガイド開発者ガイドも、ロギングについてはまったく触れていません。移行ガイドも同様です。

jboss-logging 自体に関するドキュメントを探しましたが、まったく見つかりませんでした。GitHub ページは Silentであり、JBoss のコミュニティプロジェクト ページには jboss-logging のリストさえありません。このプロジェクトのバグトラッカーには、ドキュメントの提供に関連する問題があるのではないかと思いましたが、そうではありません。

幸いなことに、JBoss AS7 などのアプリケーション サーバー内で Hibernate 4 を使用すると、ロギングの大部分が自動的に処理されます。しかし、スタンドアロン アプリケーションでどのように構成できますか?

4

11 に答える 11

62

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 へのフォールバックが試行されます。

私は一緒に使用slf4jlogback-classicます:

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

そしてすべてうまくいきます!

更新一部のユーザーは、非常にメインの App.java で使用します。

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

しかし、コンテナ ベースのソリューションでは、これは機能しません。

UPDATE 2 Log4j を SLF4J で管理していると思っている人は、そうjboss-loggingではありません。jboss-loggingSLF4JなしでLog4jを直接使用!

于 2013-10-21T07:31:02.367 に答える
27

バックエンドとして Logback を使用せずに SLF4J を JBoss Logging で動作させるには、システム プロパティを使用する必要がありますorg.jboss.logging.provider=slf4jlog4j-over-slf4jLogbackもlog4jも実際にクラスパスに存在しない場合、ロギングはJDKにフォールバックするため、この場合、戦術は機能していないようです。

これはちょっと厄介で、自動検出を機能させるために、クラスローダーに少なくともch.qos.logback.classic.Loggerlogback-classic またはorg.apache.log4j.Hierarchylog4j からのものが含まれていることがわかり、JBoss ロギングが JDK ロギングにフォールバックしないようにだますことができます。

魔法はで解釈されますorg.jboss.logging.LoggerProviders

更新: サービス ローダーのサポートが追加されたため、META-INF/services/org.jboss.logging.LoggerProvider(org.jboss.logging.Slf4jLoggerProvider値として) を宣言することで自動検出の問題を回避できます。log4j2 のサポートも追加されているようです。

于 2013-01-10T06:26:56.073 に答える
12

Leif の Hypoport 投稿に触発されて、これは私が Hibernate 4 を slf4j に「曲げる」方法です。

Maven を使用しているとします。

  • org.slf4j:log4j-over-slf4jに依存関係として追加しますpom.xml
  • コマンドを使用して、使用しているアーティファクトがどれmvn dependency:treeにも依存していないことを確認します(正確には、どのアーティファクトもコンパイルスコープの依存関係またはランタイムスコープの依存関係を持つべきではありません) 。slf4j:slf4jslf4j:slf4j

背景: Hibernate 4.x はアーティファクトに依存していますorg.jboss.logging:jboss-logging。推移的に、このアーティファクトには、アーティファクトに対する提供されたスコープの依存関係がありますslf4j:slf4j

org.slf4j:log4j-over-slf4jアーティファクトを追加したので、アーティファクトをorg.slf4j:log4j-over-slf4j模倣しslf4j:slf4jます。したがって、JBoss Loggingログに記録されるものはすべて、実際には 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 -->

logback.xml一部のコンポーネントは、Jetty Maven プラグインなど、適切なロギングのために JVM の起動時にアクセスする必要がある場合があります。その場合、logback.configurationFile=./path/to/logback.xmlコマンドに Java システムを追加します (例: mvn -Dlogback.configurationFile=./target/classes/logback.xml jetty:run)。

「未加工」のコンソール stdout Hibernate 出力 (のようなもの) をまだ取得している場合はHibernate: select ...、スタック オーバーフローの質問「コンソールへの休止状態ログをオフにする」が適用される場合があります。

于 2012-11-09T16:29:28.063 に答える
8

最初に、SLF4J はロギング ライブラリではなく、ロギング ラッパーであることがわかります。それ自体は何もログに記録せず、単に「バックエンド」に委任します。

jboss-logging を「設定」するには、使用したいログ フレームワークをクラスパスに (jboss-logging とともに) 追加するだけで、jboss-logging が残りを把握します。

JBoss Logging 設定の Hibernate に焦点を当てたガイドを作成しました: http://docs.jboss.org/hibernate/orm/4.3/topical/html/logging/Logging.html

于 2012-07-25T03:53:09.700 に答える
3

スタンドアロンアプリでHibernateCore4.1.7.Final plusSpring3.1.2.RELEASEを使用しています。Log4j 1.2.17を依存関係に追加しましたが、JBoss Loggingは利用可能な場合はlog4jに直接ログを記録し、SpringはCommons Loggingを使用し、witchも利用可能な場合はLog4jを使用するため、すべてのLoggingはLog4Jを介して構成できます。

関連する依存関係のリストは次のとおりです。

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>4.1.7.Final</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.1.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>3.1.2.RELEASE</version>
</dependency>
于 2012-10-18T09:03:04.897 に答える
3

だから、私のプロジェクトでそれを機能させました。休止状態 4、slf4j、ログバック。私のプロジェクトはgradleですが、mavenでも同じはずです。

基本的にアブドゥルは正しい。彼が正しくないところは、依存関係から slf4j を削除する必要がないということです。

  1. スコープをコンパイルするために含める:

    org.slf4j:slf4j-api

    org.slf4j:log4j-over-slf4j

    例えば、ログバック (ch.qos.logback:logback-classic、ch.qos.logback:logback-core:1.0.12) の場合

  2. 依存関係から log4j ライブラリを完全に除外する

結果: slf4j を介してログを休止状態にし、ログバックします。もちろん、logback とは異なるログ実装を使用できるはずです

log4j が存在しないことを確認するには、クラスパスまたは web-inf/lib のライブラリで war ファイルを確認します。

もちろん、logback.xml でロガーを設定しました。

<logger name="org.hibernate.SQL" level="TRACE"/>

于 2013-10-18T08:09:17.070 に答える
3

Hibernate 4.3 には、制御方法に関するドキュメントがいくつかありますorg.jboss.logging

  • ロギング プロバイダのクラスパスを検索します。log4j を検索した後、slf4j を検索します。したがって、理論的には、クラスパス (WAR) に log4j が含まれず、slf4j API とバックエンドが含まれていることを確認する必要があります。

  • org.jboss.logging.provider最後の手段として、システム プロパティを に設定できますslf4j


ドキュメントのorg.jboss.logging主張にもかかわらず、log4j が存在せず、SLF4J が存在するにもかかわらず、log4j を使用しようと主張した結果、Tomcat ログ ファイルに次のメッセージが記録されました ( /var/log/tomcat/catalina.out)。

 log4j:WARN No appenders could be found for logger (org.jboss.logging).
 log4j:WARN Please initialize the log4j system properly.
 log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

dasAnderl ausMingaによる回答の提案に従い、ブリッジを含める必要がありましたlog4j-over-slf4j

于 2014-12-15T11:14:06.617 に答える
1

私はmavenを使用し、次の依存関係を追加しました:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.6</version>
</dependency>

次に、次の場所にlog4j.propertiesファイルを作成しました/src/main/resources

# direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
# set log levels
log4j.rootLogger=warn

これにより、 のルートに配置されます.jar。それは魅力のように機能します...

于 2012-08-17T20:02:45.247 に答える
-3

これを試しましたか:

・Log4Jの場合はslf4j-log4j12.jar。詳細については、SLF4J のドキュメントを参照してください。Log4j を使用するには、クラスパスに log4j.properties ファイルを配置する必要もあります。プロパティ ファイルの例は、Hibernate とともに src/ ディレクトリに配布されています。

これらのjarとプロパティまたはlog4j xmlをクラスパスに追加するだけです

于 2012-07-24T22:21:08.000 に答える