Slf4j-quick-guide
SLF4J-概要
SLF4Jは* S imple L ogging F acade for J * avaの略です。 Javaのすべてのロギングフレームワークの単純な抽象化を提供します。 したがって、ユーザーは、単一の依存関係を使用して、Log4j、Logback、 JUL (java.util.logging)などのロギングフレームワークを操作できます。 実行時/展開時に必要なロギングフレームワークに移行できます。
CekiGülcüは、Jakarta commons-logging frameworkの代替としてSLF4Jを作成しました。
SLF4Jの利点
SLF4Jの利点は次のとおりです-
- SLF4Jフレームワークを使用すると、展開時に目的のロギングフレームワークに移行できます。
- Slf4Jは、log4j、JUL、シンプルロギング、NOPなどの一般的なすべてのロギングフレームワークへのバインディングを提供します。 したがって、展開時にこれらの一般的なフレームワークのいずれかに切り替えることができます。
- SLF4Jは、使用するバインディングに関係なく、パラメーター化されたログメッセージをサポートします。
- SLF4Jはアプリケーションとロギングフレームワークを分離しているため、ロギングフレームワークに依存しないアプリケーションを簡単に作成できます。 アプリケーションの作成に使用されるロギングフレームワークについて気にする必要はありません。
- SLF4Jは、migratorと呼ばれる単純なJavaツールを提供します。 このツールを使用すると、Jakarta Commons Logging(JCL)またはlog4jまたはJava.util.logging(JUL)などのログフレーム機能を使用する既存のプロジェクトをSLF4Jに移行できます。
SLF4J-ロギングフレームワーク
プログラミングでのログインは、アクティビティ/イベントの記録を指します。 通常、アプリケーション開発者はロギングを処理する必要があります。
ロギングの作業を簡単にするために、Javaはlog4J、java.util.logging(JUL)、小さなログ、ログバックなどのさまざまなフレームワークを提供します。
ロギングフレームワークの概要
ロギングフレームワークには通常3つの要素が含まれます-
ロガー
メタデータとともにメッセージをキャプチャします。
フォーマッタ
ロガーによってキャプチャされたメッセージをフォーマットします。
ハンドラ
ハンドラーまたはアペンダーは、コンソールに印刷するか、データベースに保存するか、電子メールで送信することにより、最終的にメッセージをディスパッチします。
一部のフレームワークは、ロガー要素とアペンダー要素を組み合わせて操作を高速化します。
ロガーオブジェクト
メッセージをログに記録するために、アプリケーションは名前とセキュリティレベルを指定してロガーオブジェクトを送信します(例外がある場合は例外も一緒に送信されます)。
重大度
ログに記録されるメッセージはさまざまなレベルになります。 次の表は、ロギングの一般的なレベルを示しています。
Sr.No | Severity level & Description |
---|---|
1 |
Fatal アプリケーションを終了させる重大な問題。 |
2 |
ERROR 実行時エラー |
3 |
WARNING ほとんどの場合、エラーは廃止されたAPIの使用が原因です。 |
4 |
INFO 実行時に発生するイベント。 |
5 |
DEBUG システムのフローに関する情報。 |
6 |
TRACE システムのフローに関する詳細情報。 |
SLF4J対Log4j
log4jとは何ですか?
log4jは、Java *で記述された信頼性が高く、高速で柔軟な*ロギングフレームワーク(API)であり、Apacheソフトウェアライセンスの下で配布されます。
log4jは、実行時に外部構成ファイルを使用して高度に構成できます。 優先度のレベルでロギングプロセスを表示し、データベース、ファイル、コンソール、UNIX Syslogなどのさまざまな宛先にロギング情報を送信するメカニズムを提供します。 (log4jの詳細については、リンク:/log4j/index [Tutorial]を参照してください)。
SLF4JとLog4jの比較
log4jとは異なり、SLF4J(* S imple L ogging F acade for J * ava)はロギングフレームワークの実装ではなく、すべてのロギングフレームワークの*抽象化です。 log4J *に似たJava。 したがって、両方を比較することはできません。 ただし、どちらか一方を優先することは常に困難です。
選択肢がある場合は、ロギングフレームワークよりもロギングの抽象化が常に望ましいです。 ロギング抽象化、特にSLF4Jを使用する場合、単一の依存関係を選択することなく、デプロイメント時に必要なロギングフレームワークに移行できます。
理解を深めるために、次の図をご覧ください。
SLF4J-環境のセットアップ
この章では、Eclipse IDEでSLF4J環境を設定する方法について説明します。 インストールを続行する前に、システムにEclipseがインストールされていることを確認してください。 そうでない場合は、Eclipseをダウンロードしてインストールします。
Eclipseの詳細については、リンクを参照してください:/eclipse/index [Eclipseチュートリアル]
ステップ1:依存関係JARファイルをダウンロードする
SLF4J Webサイトの公式https://www.slf4j.org [homepage]を開き、ダウンロードページに移動します。
次に、オペレーティングシステムに応じて、 _ slf4j-X.X.tar.gz_ または_slf4j-X.X.zip_の最新の安定バージョンをダウンロードします(Windows .zipファイルまたはLinux tar.gzファイルの場合)。
ダウンロードしたフォルダー内に、_slf4j-api-X.X.jar_があります。 これは必須のJarファイルです。
ステップ2:プロジェクトを作成してビルドパスを設定する
Eclipseを開き、サンプルプロジェクトを作成します。 プロジェクトを右クリックして、以下に示すように、* Build Path→Configure Build Path…*オプションを選択します。
[ライブラリ]タブの[Javaビルドパス]フレームで、[外部JARの追加…]をクリックします。
ダウンロードした slf4j-api.x.x.jar ファイルを選択し、*適用して閉じる*をクリックします。
SLF4Jバインディング
*slf4j-api.x.x.jar* ファイルに加えて、 *SLF4J* は以下に示すように他のいくつかのJarファイルを提供します。 これらは* SLF4Jバインディング*と呼ばれます。
各バインディングは、それぞれのロギングフレームワーク用です。
次の表に、SLF4Jバインディングとそれに対応するフレームワークを示します。
Sr.No | Jar file & Logging Framework |
---|---|
1 |
slf4j-nop-x.x.jar 操作なし。すべてのログを破棄します。 |
2 |
slf4j-simple-x.x.jar info以上のメッセージが出力され、System.errへのすべての出力を保持する単純な実装。 |
3 |
slf4j-jcl-x.x.jar Jakarta Commons Loggingフレームワーク。 |
4 |
slf4j-jdk14-x.x.jar Java.util.loggingフレームワーク(JUL)。 |
5 |
slf4j-log4j12-x.x.jar Log4Jフレームワーク。 さらに、 log4j.jar が必要です。 |
SLF4Jをslf4l-api-x.x.jarとともに動作させるには、プロジェクトのクラスパスに目的のロガーフレームワークの各Jarファイル(バインディング)を追加する必要があります(ビルドパスの設定)。
あるフレームワークから他のフレームワークに切り替えるには、それぞれのバインディングを置き換える必要があります。 境界が見つからない場合、デフォルトで無操作モードになります。
SLF4JのPom.xml
Mavenプロジェクトを作成する場合は、 pom.xml を開き、次のコンテンツをその中に貼り付けて、プロジェクトを更新します。
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Sample</groupId>
<artifactId>Sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
</project>
SLF4J-参照API
この章では、このチュートリアルの後続の章で使用するクラスとメソッドについて説明します。
ロガーインターフェース
*org.slf4j* パッケージのロガーインターフェースは、SLF4J APIのエントリポイントです。 以下に、このインターフェースの重要なメソッドをリストします。
Sr.No. | Methods and Description |
---|---|
1 |
void debug(String msg) このメソッドは、デバッグレベルでメッセージを記録します。 |
2 |
void error(String msg) このメソッドは、エラーレベルでメッセージを記録します。 |
3 |
void info(String msg) このメソッドは、INFOレベルでメッセージを記録します。 |
4 |
void trace(String msg) このメソッドは、TRACEレベルでメッセージを記録します。 |
5 |
void warn(String msg) このメソッドは、WARNレベルでメッセージを記録します。 |
LoggerFactoryクラス
*org.slf4j* パッケージのLoggerFactoryクラスはユーティリティクラスで、log4j、JUL、NOP、シンプルロガーなどのさまざまなロギングAPIのロガーを生成するために使用されます。
Sr.No. | Method and Description |
---|---|
1 |
Logger getLogger(String name) このメソッドは、名前を表す文字列値を受け取り、指定された名前の Logger オブジェクトを返します。 |
プロファイラークラス
このクラスは、パッケージ org.slf4j に属し、プロファイリングの目的で使用され、貧乏人のプロファイラーとして知られています。 これを使用して、プログラマは長時間のタスクを実行するのにかかる時間を知ることができます。
このクラスの重要なメソッドは次のとおりです。
Sr.No. | Methods and Description |
---|---|
1 |
void start(String name) このメソッドは、新しい子ストップウォッチ(名前付き)を開始し、以前の子ストップウォッチ(またはタイムインストルメント)を停止します。 |
2 |
TimeInstrument stop() このメソッドは、最近の子ストップウォッチとグローバルストップウォッチを停止し、現在の時間計測器を返します。 |
3 |
void setLogger(Logger logger) このメソッドはLoggerオブジェクトを受け入れ、指定されたロガーを現在のプロファイラーに関連付けます。 |
4 |
void log() ロガーに関連付けられている現在時刻計器の内容を記録します。 |
5 |
void print() 現在の時間計器の内容を印刷します。 |
SLF4J-Hello world
この章では、SLF4Jを使用した簡単な基本的なロガープログラムについて説明します。 以下に説明する手順に従って、簡単なロガーを作成します。
手順1-slf4j.Loggerインターフェイスのオブジェクトを作成する
*slf4j.Logger* はSLF4J APIのエントリポイントであるため、最初にそのオブジェクトを取得/作成する必要があります
*LoggerFactory* クラスの* getLogger()*メソッドは、名前を表す文字列値を受け入れ、指定された名前の *Logger* オブジェクトを返します。
Logger logger = LoggerFactory.getLogger("SampleLogger");
ステップ2-必要なメッセージを記録する
*slf4j.Logger* インターフェースの* info()*メソッドは、必要なメッセージを表す文字列値を受け入れ、情報レベルでログに記録します。
logger.info("Hi This is my first SLF4J program");
例
以下は、SLF4Jを使用してJavaでサンプルロガーを作成する方法を示すプログラムです。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JExample {
public static void main(String[] args) {
//Creating the Logger object
Logger logger = LoggerFactory.getLogger("SampleLogger");
//Logging the information
logger.info("Hi This is my first SLF4J program");
}
}
出力
最初に次のプログラムを実行すると、目的のメッセージの代わりに次の出力が表示されます。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codesl#StaticLoggerBinder for further
details.
このチュートリアルで前述したように、ロギングフレームワークを表すバインディングにクラスパスを設定していないため、SLF4Jはデフォルトで無操作の実装になりました。 そのため、メッセージを表示するには、プロジェクトクラスパスに目的のバインディングを追加する必要があります。 Eclipseを使用しているため、それぞれのJARファイルに build path を設定するか、pom.xmlファイルに依存関係を追加します。
たとえば、JUL(Java.util.logging framework)を使用する必要がある場合、jarファイル slf4j-jdk14-x.x.jar のビルドパスを設定する必要があります。 また、log4Jロギングフレームワークを使用する場合は、ビルドパスを設定するか、jarファイル slf4j-log4j12-x.x.jar および log4j.jar の依存関係を追加する必要があります。
*slf4j-nopx.x.jar* 以外のロギングフレームワークを表すバインディングをプロジェクト(クラスパス)に追加すると、次の出力が得られます。
Dec 06, 2018 5:29:44 PM SLF4JExample main
INFO: Hi Welcome to finddevguides
SLF4J-エラーメッセージ
この章では、SLF4Jの操作中に表示されるさまざまなエラーメッセージまたは警告と、それらのメッセージの原因/意味について説明します。
クラス「org.slf4j.impl.StaticLoggerBinder」のロードに失敗しました。
これは、クラスパスでSLF4Jバインディングが提供されていない場合に発生する警告です。
以下は完全な警告です-
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codesl#StaticLoggerBinder for further
details.
これを解決するには、ロギングフレームワークバインディングのいずれかを追加する必要があります。 これについては、このチュートリアルの Hello world の章で説明されています。
注-これは、1.6.0〜1.8.0-beta2のSLF4Jのバージョンで発生します。
SLF4Jプロバイダーが見つかりませんでした
slf4j-1.8.0-beta2では、*「SLF4Jプロバイダーが見つかりませんでした」*という上記の警告はより明確です。
以下は完全な警告です-
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codesl#noProviders for further details.
クラスパスには、slf4j-apiバージョン1.8より前をターゲットとするSLF4Jバインディングが含まれています
SLF4J 1.8バージョンを使用しており、クラスパスに以前のバージョンのバインディングがあるが1.8のバインディングがない場合は、次のような警告が表示されます。
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codesl#noProviders for further details.
SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions prior to
1.8.
SLF4J: Ignoring binding found at
[jar:file:/C:/Users/finddevguides/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-jdk14-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codesl#ignoredBindings for an explanation.
NoClassDefFoundError:org/apache/commons/logging/LogFactory
*slf4j-jcl* を使用していて、クラスパスに *slf4j-jcl.jar* しかない場合、以下のような例外が発生します。
Exception in thread "main" java.lang.NoClassDefFoundError:
org/apache/commons/logging/LogFactory
at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:77)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.ClassNotFoundException:
org.apache.commons.logging.LogFactory
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more
これを解決するには、 commons-logging.jar をクラスパスに追加する必要があります。
クラスパスでjcl-over-slf4j.jarとバインドされたslf4j-jcl.jarの両方を検出しました。
バインディング slf4j-jcl.jar はslf4jロガーの呼び出しをJCLにリダイレクトし、 jcl-over-slf4j.jar はJCLロガーの呼び出しをslf4jにリダイレクトします。 したがって、プロジェクトのクラスパスに両方を含めることはできません。 これを行うと、次のような例外が発生します。
SLF4J: Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the class
path, preempting StackOverflowError.
SLF4J: See also http://www.slf4j.org/codesl#jclDelegationLoop for more
details.
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:71)
at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:42)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.IllegalStateException: Detected both jcl-over-slf4j.jar
AND bound slf4j-jcl.jar on the class path, preempting StackOverflowError. See
also http://www.slf4j.org/codesl#jclDelegationLoop for more details.
at org.slf4j.impl.JCLLoggerFactory.<clinit>(JCLLoggerFactory.java:54)
... 7 more
これを解決するには、いずれかのjarファイルを削除します。
ロガー名の不一致が検出されました
次の方法でLoggerオブジェクトを作成できます-
- * getLogger()*メソッドの引数として作成されるロガーの名前を渡します。
- このメソッドに引数としてクラスを渡す。
クラスを引数として渡すことによってロガーファクトリオブジェクトを作成しようとしている場合、およびシステムプロパティ slf4j.detectLoggerNameMismatch をtrueに設定している場合は、引数として* getLogger( )*メソッドと使用するクラスは同じでなければなりません。そうしないと、次の警告が表示されます-
「ロガー名の不一致が検出されました。
次の例を考えてください。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JExample {
public static void main(String[] args) {
System.setProperty("slf4j.detectLoggerNameMismatch", "true");
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("Hi Welcome to Tutorilspoint");
}
}
ここでは、_slf4j.detectLoggerNameMismatch_プロパティをtrueに設定しました。 使用したクラスの名前は SLF4JExample で、getLogger()メソッドに渡したクラス名は Sample です。これらは両方とも等しくないため、次の警告が表示されます。
SLF4J: Detected logger name mismatch. Given name: "Sample"; computed name:
"SLF4JExample".
SLF4J: See http://www.slf4j.org/codesl#loggerNameMismatch for an
explanation
Dec 10, 2018 12:43:00 PM SLF4JExample main
INFO: Hi Welcome to Tutorilspoint
注-これはslf4j 1.7.9の後に発生します
クラスパスには複数のSLF4Jバインディングが含まれます。
クラスパスにはバインディングが1つしかありません。 複数のバインディングがある場合、バインディングとそれらの場所をリストする警告が表示されます。
たとえば、クラスパスに slf4j-jdk14.jar と slf4j-nop.jar のバインディングがある場合、次の警告が表示されます。
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in
[jar:file:/C:/Users/finddevguides/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-nop-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in
[jar:file:/C:/Users/finddevguides/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-jdk14-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codesl#multiple_bindings for an
explanation.
SLF4J: Actual binding is of type [org.slf4j.helpers.NOPLoggerFactory]
クラスパスでlog4j-over-slf4j.jarとバインドされたslf4j-log4j12.jarの両方を検出しました
log4jロガーコールをslf4jにリダイレクトするには、 log4j-over-slf4j.jar バインディングを使用する必要があります。slf4jコールをlog4jにリダイレクトするには、 slf4j-log4j12.jar バインディングを使用する必要があります。
したがって、クラスパスに両方を含めることはできません。 その場合、次の例外が発生します。
SLF4J: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the
class path, preempting StackOverflowError.
SLF4J: See also http://www.slf4j.org/codesl#log4jDelegationLoop for more
details.
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72)
at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar
AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError.
See also http://www.slf4j.org/codesl#log4jDelegationLoop for more details.
SLF4J-パラメーター化されたロギング
このチュートリアルで前述したように、SLF4Jはパラメーター化されたログメッセージのサポートを提供します。
メッセージでパラメーターを使用し、後で同じステートメントで値を渡すことができます。
構文
以下に示すように、メッセージ(文字列)で必要な場所でプレースホルダー(\ {})を使用する必要があり、後で object 形式でプレースホルダーの値を渡すことができます。
Integer age;
Logger.info("At the age of {} ramu got his first job", age);
例
次の例は、SLF4Jを使用したパラメーター化されたロギング(単一パラメーター)を示しています。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(PlaceHolders.class);
Integer age = 23;
//Logging the information
logger.info("At the age of {} ramu got his first job", age);
}
}
出力
実行時に、上記のプログラムは次の出力を生成します-
Dec 10, 2018 3:25:45 PM PlaceHolders main
INFO: At the age of 23 Ramu got his first job
パラメータ化されたロギングの利点
Javaでは、ステートメントに値を出力する必要がある場合、連結演算子を次のように使用します-
System.out.println("At the age of "+23+" ramu got his first job");
これには、整数値23の文字列への変換と、この値を周囲の文字列への連結が含まれます。
それがロギングステートメントであり、ステートメントの特定のログレベルが無効になっている場合、この計算はすべて役に立ちません。
このような状況では、パラメーター化されたログを使用できます。 この形式では、最初にSLF4Jは特定のレベルのロギングが有効になっているかどうかを確認します。 その場合、メッセージのプレースホルダーをそれぞれの値に置き換えます。
たとえば、次のようなステートメントがある場合
Integer age;
Logger.debug("At the age of {} ramu got his first job", age);
デバッグが有効になっている場合にのみ、SLF4Jは年齢を整数に変換し、それ以外の場合は文字列と連結します。 したがって、ロギングレベルが無効になっている場合、パラメーター構築のコストが発生します。
2つの引数のバリアント
また、メッセージで2つのパラメータを使用することができます-
logger.info("Old weight is {}. new weight is {}.", oldWeight, newWeight);
例
次の例は、パラメーター化されたロギングでの2つのプレースホルダーの使用方法を示しています。
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
Integer oldWeight;
Integer newWeight;
Scanner sc = new Scanner(System.in);
System.out.println("Enter old weight:");
oldWeight = sc.nextInt();
System.out.println("Enter new weight:");
newWeight = sc.nextInt();
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("Old weight is {}. new weight is {}.", oldWeight, newWeight);
//Logging the information
logger.info("After the program weight reduced is: "+(oldWeight-newWeight));
}
}
出力
実行すると、上記のプログラムは次の出力を生成します。
Enter old weight:
85
Enter new weight:
74
Dec 10, 2018 4:12:31 PM PlaceHolders main
INFO: Old weight is 85. new weight is 74.
Dec 10, 2018 4:12:31 PM PlaceHolders main
INFO: After the program weight reduced is: 11
複数引数バリアント
また、次の例に示すように3つ以上のプレースホルダーを使用することができます-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
Integer age = 24;
String designation = "Software Engineer";
String company = "Infosys";
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("At the age of {} ramu got his first job as a {} at {}", age, designation, company);
}
}
出力
実行時に、上記のプログラムは次の出力を生成します-
Dec 10, 2018 4:23:52 PM PlaceHolders main
INFO: At the age of 24 ramu got his first job as a Software Engineer at Infosys
SLF4J-移行者
Jakarta Commons Logging(JCL)またはlog4jまたはjava.util.logging(JUL)にプロジェクトがあり、これらのプロジェクトをSLF4Jに変換する場合は、SLF4Jディストリビューションで提供される移行ツールを使用して行うことができます。
SLF4J Migratorの実行
SLF4Jは単純な単一のjarファイル(slf4j-migrator.jar)であり、java –jarコマンドを使用して実行できます。
これを実行するには、コマンドプロンプトで、このjarファイルがあるディレクトリを参照し、次のコマンドを実行します。
java -jar slf4j-migrator-1.8.0-beta2.jar
Starting SLF4J Migrator
これにより移行が開始され、スタンドアロンJavaアプリケーションが次のように表示されます-
ウィンドウで指定されているように、実行する移行のタイプを確認し、プロジェクトディレクトリを選択して、[プロジェクトをSLF4Jに移行]ボタンをクリックする必要があります。
このツールは、指定したソースファイルに移動し、インポート行やロガー宣言を現在のロギングフレームワークからSLF4jに変更するなどの簡単な変更を実行します。
例
たとえば、次のように、単一のファイルを持つEclipseのサンプル* log4j(2)*プロジェクトがあるとします-
import org.apache.log4j.Logger;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class Sample {
/*Get actual class name to be printed on*/
static Logger log = Logger.getLogger(Sample.class.getName());
public static void main(String[] args)throws IOException,SQLException {
log.debug("Hello this is a debug message");
log.info("Hello this is an info message");
}
}
サンプル* log4j(2)プロジェクトをslf4jに移行するには、ラジオボタン *log4jからslf4j をチェックし、プロジェクトのディレクトリを選択し、 Exit をクリックして移行する必要があります。
移行者は上記のコードを次のように変更しました。 ここでimportおよびloggerステートメントが変更されているのを観察した場合。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class Sample {
static Logger log = LoggerFactory.getLogger(Sample.class.getName());
public static void main(String[] args)throws IOException,SQLException {
log.debug("Hello this is a debug message");
log.info("Hello this is an info message");
}
}
プロジェクトに log4j.jar がすでにあるので、それを実行するにはプロジェクトに slf4j-api.jar および slf4jlog12.jar ファイルを追加する必要があります。
SLF4JMigratorの制限
SLF4J移行の制限事項は次のとおりです。
- Migratorは、ant、maven、ivyなどのビルドスクリプトを自分で行う必要はありません。
- Migratorは、Stringタイプ以外のメッセージをサポートしていません。
- MigratorはFATALレベルをサポートしていません。
- log4jでの作業中、migratorはPropertyConfiguratorまたはDomConfiguratorへの呼び出しを移行しません。
SLF4J-プロファイリング
SLF4Jディストリビューションは、 slf4j-ext.jar を提供します。これには、プロファイリング、拡張ログ、イベントログ、Javaエージェントによるログなどの機能用のAPIが含まれています。
プロファイリング
プログラマーは、メモリの使用、時間の複雑さ、またはプログラムに関する特定の命令の使用などの属性を測定して、そのプログラムの実際の能力を測定したいことがあります。 このようなプログラムに関する測定は、プロファイリングと呼ばれます。 プロファイリングでは、動的プログラム分析を使用してこのような測定を行います。
SLF4Jは、プロファイリング用に org.slf4j.profiler パッケージに Profiler という名前のクラスを提供します。 これは貧乏人のプロファイラーとして知られています。 これを使用して、プログラマは長時間のタスクを実行するのにかかる時間を知ることができます。
Profilerクラスを使用したプロファイリング
プロファイラーにはストップウォッチと子ストップウォッチが含まれており、プロファイラークラスによって提供されるメソッドを使用してこれらを開始および停止できます。
プロファイラクラスを使用してプロファイリングを続行するには、以下の手順に従います。
ステップ1-プロファイラークラスのインスタンス化
プロファイラーの名前を表す文字列値を渡すことにより、プロファイラークラスをインスタンス化します。 Profilerクラスをインスタンス化すると、グローバルストップウォッチが開始されます。
//Creating a profiler
Profiler profiler = new Profiler("Sample");
ステップ2-子ストップウォッチを開始する
- start()*メソッドを呼び出すと、新しい子ストップウォッチ(名前付き)が開始され、以前の子ストップウォッチ(または時間計測器)が停止します。
作成する子ストップウォッチの名前を表すString値を渡すことにより、 Profiler クラスの* start()*メソッドを呼び出します。
//Starting a child stopwatch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
これらのストップウォッチを作成したら、タスクを実行するか、タスクを実行するメソッドを呼び出すことができます。
ステップ3:別の子ストップウォッチを開始する(必要な場合)
必要に応じて、* start()*メソッドを使用して別のストップウォッチを作成し、必要なタスクを実行します。 そうすると、新しいストップウォッチが開始され、前のストップウォッチが停止します(つまり、 タスク1)。
//Starting another child stopwatch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
ステップ4:時計を停止する
- stop()*メソッドを呼び出すと、最近の子ストップウォッチとグローバルストップウォッチが停止し、現在のタイムインストゥルメントが返されます。
//Stopping the current child stopwatch and the global stopwatch.
TimeInstrument tm = profiler.stop();
ステップ5:計器の内容を印刷します。
- print()*メソッドを使用して、現在の時間計測器の内容を印刷します。
//printing the contents of the time instrument
tm.print();
例
次の例は、SLF4Jのプロファイラークラスを使用したプロファイリングを示しています。 ここでは、1から10000までの数値の平方和を印刷し、1から10000までの数値の合計を印刷する2つのサンプルタスクを取りました。 これら2つのタスクにかかる時間を取得しようとしています。
import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;
public class ProfilerExample {
public void demoMethod1(){
double sum = 0;
for(int i=0; i< 1000; i++){
sum = sum+(Math.pow(i, 2));
}
System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
}
public void demoMethod2(){
int sum = 0;
for(int i=0; i< 10000; i++){
sum = sum+i;
}
System.out.println("Sum of the numbers from 1 to 10000: "+sum);
}
public static void main(String[] args) {
ProfilerExample obj = new ProfilerExample();
//Creating a profiler
Profiler profiler = new Profiler("Sample");
//Starting a child stop watch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
//Starting another child stop watch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
//Stopping the current child watch and the global watch.
TimeInstrument tm = profiler.stop();
//printing the contents of the time instrument
tm.print();
}
}
出力
実行時に、上記のプログラムは次の出力を生成します-
Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000
+ Profiler [BASIC]
|-- elapsed time [Task 1] 2291.827 microseconds.
|-- elapsed time [Task 2] 225.802 microseconds.
|-- Total [BASIC] 3221.598 microseconds.
プロファイラー情報のログ
プロファイラーの結果を印刷してこの情報を記録する代わりに、以下を行う必要があります-
- LoggerFactory クラスを使用してロガーを作成します。
- Profilerクラスをインスタンス化して、プロファイラーを作成します。
- 作成されたロガーオブジェクトを Profiler クラスの* setLogger()*メソッドに渡すことにより、ロガーをプロファイラーに関連付けます。
- 最後に、* log()*メソッドを使用してプロファイラーの情報をログ出力する代わりに。
例
次の例では、前の例とは異なり(印刷の代わりに)、時間計測器の内容を記録しようとしています。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;
public class ProfilerExample_logger {
public void demoMethod1(){
double sum = 0;
for(int i=0; i< 1000; i++){
sum = sum+(Math.pow(i, 2));
}
System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
}
public void demoMethod2(){
int sum = 0;
for(int i=0; i< 10000; i++){
sum = sum+i;
}
System.out.println("Sum of the numbers from 1 to 10000: "+sum);
}
public static void main(String[] args) {
ProfilerExample_logger obj = new ProfilerExample_logger();
//Creating a logger
Logger logger = LoggerFactory.getLogger(ProfilerExample_logger.class);
//Creating a profiler
Profiler profiler = new Profiler("Sample");
//Adding logger to the profiler
profiler.setLogger(logger);
//Starting a child stop watch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
//Starting another child stop watch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
//Stopping the current child watch and the global watch.
TimeInstrument tm = profiler.stop();
//Logging the contents of the time instrument
tm.log();
}
}
出力
実行すると、上記のプログラムは次の出力を生成します。
Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000