Javaロギング・フレームワーク:SLF4Jコメント

SLF4Jの概要

Javaのための簡単なロギングファサード(SLF4J)は、のjava.util.logging、logbackとlog4jのような様々なロギング・フレームワークのための単純なファサード又は抽象として機能します。SLF4Jは、エンドユーザが、展開時に所望のロギング・フレームワークにプラグインすることを可能にします。

Simple Logging Facade for Java抽象的又は単純な外観(SLF4J)フレームは、例えば、各種のログとして使用することができるjava.util.logginglogbacklog4jSLF4Jロギングフレームワークは、エンドユーザーが必要な展開を挿入することができます。

デプロイメント時にログフレームワークとの結合

SLF4JいくつかのJARファイルを持つ分布発送と呼ばれるSLF4J bindings各結合サポートフレームワークに対応します。

  • SLF4J-log4j12-1.7.27.jar

    バインディングlog4j version 1.2、広く使われているロギングフレームワークを。また、配置する必要がありlog4j.jar、あなたのクラスパスに。

  • SLF4J-jdk14-1.7.27.jar

    バインディングjava.util.loggingもJDK 1.4ログと呼ばれます、

  • SLF4J-NOP-1.7.27.jar

    静かにすべてのログを破棄し、NOPのバインディング。

  • SLF4J-単純1.7.27.jar

    System.errにすべてのイベントを出力単純な実装のためのバインディング。レベルINFOと高いのメッセージだけが印刷されます。この結合は、小さなアプリケーションのコンテキストで有用である可能性があります。

  • SLF4J-JCL-1.7.27.jar

    バインディングJakarta Commons Loggingこの結合は、JCLに、すべてのSLF4Jロギングを委譲します。

  • logback-古典-1.2.3.jar(logbackコア-1.2.3.jarが必要)

    SLF4Jプロジェクトへの外部SLF4Jバインディングもありますが、Logback's ch.qos.logback.classic.LoggerこのクラスはSLF4Jの直接の実装ですorg.slf4j.Loggerインターフェイス。

ログフレームワークを切り替えるには、ちょうどあなたのクラスパス上SLF4Jバインディングを交換してください。例えば、log4jのにjava.util.loggingを切り替えるだけでSLF4J-jdk14-1.7.27.jar SLF4J-log4j12-1.7.27.jarと交換します。

ロギングフレームワークを切り替えるには、SLF4Jは、単純に結合クラスパスを交換してください。例えば、のlog4jのjava.util.loggingから切り替えるには、単にSLF4J-log4j12-1.7.27.jarができるようにSLF4J-jdk14-1.7.27.jar交換してください。

SLF4Jは、特別なクラスローダ機械に依存しません。実際には、結合各SLF4Jは、唯一の特定のロギングフレームワークを使用するようにコンパイル時にハードワイヤードされます例えば、SLF4J-log4j12-1.7.27.jar結合は、log4jのを使用するようにコンパイル時にバインドされています。あなたのコードでは、ほかにSLF4J-API-1.7.27.jarをするには、単に1をドロップし、唯一の適切なクラスパスの場所にお好みの結合します。あなたのクラスパス上に結合つ以上を置かないでください。

SLF4J経由でログを統合(SLF4J連結ログインすることで)

SLF4Jは、JCL、のjava.util.loggingとlog4jのためのブリッジングモジュールを提供することによって、この共通のユースケースにも対応しています。

、ブリッジモジュールSLF4J JCLを提供するのlog4jを持つjava.util.loggingし、この一般的な使用例を満たすことによって。

マップされた診断コンテキスト(MDC)のサポート

Mapped Diagnostic Context本質的に、アプリケーション・コードは、ログメッセージにロギング・フレームワークによって挿入することができるキーと値のペアを提供するロギング・フレームワークによって維持されるマップです。MDCデータはまた、メッセージのフィルタリングや特定のアクションをトリガーするのに非常に役立ちます。

診断コンテキストをマッピングすることは、本質的に、アプリケーション・コードは、キーと値のペアを提供し、ここで、ログフレームマッピングによって維持され、その後、ロギング・フレームワーク・ログ・メッセージは、対を挿入することができます。MDCデータは、特定のフィルタリング動作又はトリガメッセージにも有用です。

SLF4JサポートしているMDC、または診断コンテキストをマッピングされました。基本的なログフレームワークを提供する場合MDCの機能を、そしてSLF4J基本的なフレームワークのMDCに委譲します。なお、このときだけlog4jlogback提供MDC機能を。基本となるフレームワークが提供していない場合はMDC、例えばjava.util.logging、その後、SLF4Jまだ保存するMDCデータをが、情報は、その中に、カスタムユーザーコードによって取得する必要があります。

SLF4J支持MDCまたはマップ診断コンテキスト。基本的なログフレームワークは、MDCの機能を提供する場合、そのSLF4Jは、MDCの根本的な枠組みに委託されます。現在、MDC logback log4jの機能を提供しますのでご注意ください。基礎となるフレームワークは、MDCを提供しない場合、のjava.util.loggingは、例えば、MDC SLF4Jデータがまだ保存されますが、情報はカスタムユーザコードによって検索される必要があります。

原理分析

図に示すことでSLF4J、抽象様々な特定のロギングフレームワークをされることができるStaticLoggerBinderクラスを完了しました。次に、フォーカスを見てbind()方法は、見つける方法でStaticLoggerBinder、次のようにクラスのソースコードを:

private final static void bind() {
    try {
        // 查找类路径下所有的StaticLoggerBinder类
        Set<URL> staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
        // 如果存在多个StaticLoggerBinder类,则打印日志
        reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
        // 获取StaticLoggerBinder实例,如果不存在,则抛出NoClassDefFoundError异常
        StaticLoggerBinder.getSingleton();
        INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
        // 打印实际使用StaticLoggerBinder类
        reportActualBinding(staticLoggerBinderPathSet);
        fixSubstitutedLoggers();
    } catch (NoClassDefFoundError ncde) {
        String msg = ncde.getMessage();
        if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
            INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
            Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
            Util.report("Defaulting to no-operation (NOP) logger implementation");
            Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
        } else {
            failedBinding(ncde);
            throw ncde;
        }
    } catch (java.lang.NoSuchMethodError nsme) {
        String msg = nsme.getMessage();
        if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
            INITIALIZATION_STATE = FAILED_INITIALIZATION;
            Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
            Util.report("Your binding is version 1.5.5 or earlier.");
            Util.report("Upgrade your binding to version 1.6.x.");
        }
        throw nsme;
    } catch (Exception e) {
        failedBinding(e);
        throw new IllegalStateException("Unexpected initialization failure", e);
    }
}

private static String  STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";

private static Set<URL> findPossibleStaticLoggerBinderPathSet() {
    Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
    try {
        ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
        Enumeration<URL> paths;
        if (loggerFactoryClassLoader == null) {
            paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
        } else {
            paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
        }
        while (paths.hasMoreElements()) {
            URL path = (URL) paths.nextElement();
            staticLoggerBinderPathSet.add(path);
        }
    } catch (IOException ioe) {
        Util.report("Error getting resources from path", ioe);
    }
    return staticLoggerBinderPathSet;
}
复制代码

logbackと統合SLF4J

  1. Mavenの依存関係を次のように:

    <!-- slf4j-api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.12</version>
    </dependency>
    <!-- logback -->
    <dependency> 
        <groupId>ch.qos.logback</groupId> 
        <artifactId>logback-core</artifactId> 
        <version>1.1.3</version> 
    </dependency>
    <!-- logback-classic(已含有对slf4j的集成包) --> 
    <dependency> 
        <groupId>ch.qos.logback</groupId> 
        <artifactId>logback-classic</artifactId> 
        <version>1.1.3</version> 
    </dependency>
    复制代码
  2. logbackプロファイルlogback.xmlを書く次のように、読み取ります。

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
      </appender>
      <root level="DEBUG">          
        <appender-ref ref="STDOUT" />
      </root>  
    </configuration>
    复制代码
  3. 使用

    private static final Logger logger=LoggerFactory.getLogger(LogbackTest.class);
    public static void main(String[] args){
        if(logger.isDebugEnabled()){
            logger.debug("slf4j-logback debug message");
        }
        if(logger.isInfoEnabled()){
            logger.info("slf4j-logback info message");
        }
        if(logger.isTraceEnabled()){
            logger.trace("slf4j-logback trace message");
        }
    }
    复制代码
  4. org.slf4j.impl.StaticLoggerBinderクラスの実装


log4と統合SLF4J

  1. Mavenの依存関係を次のように:

    <!-- slf4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.12</version>
    </dependency>
    
    <!-- slf4j-log4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.12</version>
    </dependency>
    
    <!-- log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    复制代码
  2. クラスパスにlog4j.propertiesの設定ファイルを書きます

    log4j.rootLogger = debug, console
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %m%n
    复制代码
  3. 使用

    private static Logger logger=LoggerFactory.getLogger(Log4j2Slf4jTest.class);
    public static void main(String[] args){
        if(logger.isTraceEnabled()){
            logger.trace("slf4j-log4j2 trace message");
        }
        if(logger.isDebugEnabled()){
            logger.debug("slf4j-log4j2 debug message");
        }
        if(logger.isInfoEnabled()){
            logger.info("slf4j-log4j2 info message");
        }
    }
    复制代码
  4. org.slf4j.impl.StaticLoggerBinderクラスの実装


参考資料

統合された原則JCLと7月、log4j1、log4j2のlogback

おすすめ

転載: juejin.im/post/5d85ac86f265da03d316fd6a