SLF4Jの概要
Javaのための簡単なロギングファサード(SLF4J)は、のjava.util.logging、logbackとlog4jのような様々なロギング・フレームワークのための単純なファサード又は抽象として機能します。SLF4Jは、エンドユーザが、展開時に所望のロギング・フレームワークにプラグインすることを可能にします。
Simple Logging Facade for Java
抽象的又は単純な外観(SLF4J)フレームは、例えば、各種のログとして使用することができるjava.util.logging
、logback
とlog4j
。SLF4J
ロギングフレームワークは、エンドユーザーが必要な展開を挿入することができます。
デプロイメント時にログフレームワークとの結合
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に委譲します。なお、このときだけlog4j
とlogback
提供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
-
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> 复制代码
-
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> 复制代码
-
使用
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"); } } 复制代码
-
org.slf4j.impl.StaticLoggerBinder
クラスの実装
log4と統合SLF4J
-
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> 复制代码
-
クラスパスに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 复制代码
-
使用
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"); } } 复制代码
-
org.slf4j.impl.StaticLoggerBinder
クラスの実装