web-dev-qa-db-ja.com

slf4jにログバックの使用を強制する

とにかく、slf4jに特定のロギングプロバイダー(私の場合はlogback)を使用するように強制することはできますか?彼らのドキュメントのように:

クラスパスで複数のバインディングが見つかりました

SLF4J APIは、一度に1つだけの基礎となるロギングフレームワークにバインドするように設計されています。クラスパスに複数のバインディングが存在する場合、SLF4Jは警告を発し、それらのバインディングの場所をリストします。クラスパスで複数のバインディングが使用可能な場合は、使用するバインディングを1つだけ選択し、他のバインディングを削除します。たとえば、クラスパスにslf4j-> simple-1.6.6.jarとslf4j-nop-1.6.6.jarの両方があり、nop(> no-operation)バインディングを使用する場合は、slf4j-を削除します。クラスパスからのsimple-1.6.6.jar。余分なバインディングを削除できない場合でも、SLF4Jは1つのロギングフレームワーク/実装でバインドします。バージョン1.6.6以降、SLF4Jは、実際にバインドされているフレームワーク/実装クラスに名前を付けます。

注SLF4Jが発する警告は、まさにその警告です。

私の場合、クラスパスにlog4j.jarslf4j-log4j12.jarlog4j-over-slf4j.jarおよびすべてのログバックjarがあります。 slf4j-log4j12.jarlog4j-over-slf4j.jarを一緒にするのはエラーであることは知っていますが、私のプロジェクトは非常に大きく、Mavenの依存関係を見つけて除外するのは必ずしも簡単ではありません。この場合、ログバック構成のみを使用するため、slf4jは警告を出力しませんでした。この瓶の地獄を理解するのに1日かかりました。

たとえば、slf4jがJVM引数を介してログバックを使用するように強制するだけで、警告を出力でき、将来的にjarを除外できます。

28
madhead

クラスパスをクリーンアップする以外に、SLF4Jを特定の実装にバインドするように強制する方法はありません。

16
Ceki

通常、独自のコードはクラスパスの先頭にあります。このため、これを行う1つの方法は、独自のorg.slf4j.impl.StaticLoggerBinderクラスを作成することです。

package org.slf4j.impl;

import org.slf4j.ILoggerFactory;
import org.slf4j.spi.LoggerFactoryBinder;

/**
 * Force tests to use JDK14 for logging.
 */
@SuppressWarnings("UnusedDeclaration")
public class StaticLoggerBinder implements LoggerFactoryBinder {
    private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();

    public static String REQUESTED_API_VERSION = "1.6";

    public static final StaticLoggerBinder getSingleton() {
      return SINGLETON;
    }

    private StaticLoggerBinder() {
    }

    @Override
    public ILoggerFactory getLoggerFactory() {
        return new JDK14LoggerFactory();
    }

    @Override
    public String getLoggerFactoryClassStr() {
        return "org.slf4j.impl.JDK14LoggerFactory";
    }
}
22
Eric Pabst