ログバックのガイド
1. 概要
Logback は、Javaコミュニティで最も広く使用されているロギングフレームワークの1つです。 これは、その前身であるLog4jの置換です。 Logbackは、より高速な実装を提供し、構成のためのより多くのオプションを提供し、古いログファイルをアーカイブする際の柔軟性を高めます。
このチュートリアルでは、Logbackのアーキテクチャを紹介し、それを使用してアプリケーションを改善する方法を検討します。
2. ログバックアーキテクチャ
ログバックアーキテクチャは、 Logger 、 Appender 、およびLayoutの3つのクラスで構成されています。
Logger は、ログメッセージのコンテキストです。 これは、アプリケーションがログメッセージを作成するために対話するクラスです。
Appenders は、ログメッセージを最終的な宛先に配置します。 ロガーには、複数のアペンダーを含めることができます。 通常、 Appenders はテキストファイルに添付されていると考えられていますが、Logbackはそれよりもはるかに強力です。
Layoutは出力用のメッセージを準備します。 Logbackは、メッセージをフォーマットするためのカスタムクラスの作成、および既存のメッセージの堅牢な構成オプションをサポートします。
3. 設定
3.1. Mavenの依存関係
Logbackは、Simple Logging Facade for Java(SLF4J)をネイティブインターフェイスとして使用します。 メッセージのロギングを開始する前に、LogbackとSLF4Jをpom.xmlに追加する必要があります。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
<scope>test</scope>
</dependency>
Maven Centralには、最新バージョンのLogbackCoreと最新バージョンのslf4j-apiがあります。
3.2. クラスパス
ログバックには、実行時のクラスパスにlogback-classic.jarも必要です。
これをテスト依存関係としてpom.xmlに追加します。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
4. 基本的な例と構成
アプリケーションでLogbackを使用する簡単な例から始めましょう。
まず、構成ファイルが必要です。 logback.xml という名前のテキストファイルを作成し、クラスパスのどこかに配置します。
<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>
次に、mainメソッドを使用した単純なクラスが必要です。
public class Example {
private static final Logger logger
= LoggerFactory.getLogger(Example.class);
public static void main(String[] args) {
logger.info("Example log from {}", Example.class.getSimpleName());
}
}
このクラスはLoggerを作成し、 info()を呼び出してログメッセージを生成します。
Example、を実行すると、メッセージがコンソールに記録されます。
20:34:22.136 [main] INFO Example - Example log from Example
Logbackが非常に人気がある理由は簡単にわかります。 数分で稼働します。
この構成とコードは、これがどのように機能するかについていくつかのヒントを提供します。
- クラス名ConsoleAppender。を参照するSTDOUTという名前のappenderがあります。
- ログメッセージの形式を説明するパターンがあります。
- このコードはLoggerを作成し、 info()method。を介してメッセージを渡しました。
基本を理解したので、詳しく見ていきましょう。
5. ロガーコンテキスト
5.1. コンテキストの作成
メッセージをLogbackに記録するには、SLF4JまたはLogbackからLoggerを初期化します。
private static final Logger logger
= LoggerFactory.getLogger(Example.class);
次に、それを使用します。
logger.info("Example log from {}", Example.class.getSimpleName());
これがロギングコンテキストです。 作成時に、LoggerFactoryクラスを渡しました。 これはロガー名前(を受け入れるオーバーロードもあります
ロギングコンテキストは、Javaオブジェクト階層によく似た階層に存在します。
- logger は、その名前の後にドットが続き、子孫loggerの名前の前に付けられた場合の祖先です。
- ロガーは、そのロガーと子の間に祖先がない場合は親です。
たとえば、以下の Example クラスは、com.baeldung.logbackパッケージに含まれています。 com.baeldung.logback.appendersパッケージにはExampleAppenderという名前の別のクラスがあります。
ExampleAppenderのロガーは、Exampleのロガーの子です。
すべてのロガーは、事前定義されたルートロガーの子孫です。
LoggerにはLevel、があり、構成または Logger.setLevel()を使用して設定できます。コードでレベルを設定すると、構成ファイルが上書きされます。
可能なレベルは、優先順位の順に、 TRACE、DEBUG、INFO、WARN 、ERRORです。 各レベルには、ログに記録するために使用する対応するメソッドがあります。そのレベルでのメッセージ。
ロガーにレベルが明示的に割り当てられていない場合、ロガーは最も近い祖先のレベルを継承します。ルートロガーのデフォルトはDEBUGです。これをオーバーライドする方法を以下で説明します。
5.2. コンテキストの使用
ロギング階層内のコンテキストの使用を示すサンプルプログラムを作成しましょう。
ch.qos.logback.classic.Logger parentLogger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.baeldung.logback");
parentLogger.setLevel(Level.INFO);
Logger childlogger =
(ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.baeldung.logback.tests");
parentLogger.warn("This message is logged because WARN > INFO.");
parentLogger.debug("This message is not logged because DEBUG < INFO.");
childlogger.info("INFO == INFO");
childlogger.debug("DEBUG < INFO");
これを実行すると、次のメッセージが表示されます。
20:31:29.586 [main] WARN com.baeldung.logback - This message is logged because WARN > INFO.
20:31:29.594 [main] INFO com.baeldung.logback.tests - INFO == INFO
まず、com.baeldung.logbackという名前のLoggerを取得し、ch.qos.logback.classic.Logger。にキャストします。
次のステートメントでレベルを設定するには、ログバックコンテキストが必要です。 SLF4Jの抽象ロガーはsetLevel()。を実装していないことに注意してください。
コンテキストのレベルをINFOに設定します。 次に、com.baeldung.logback.tests。という名前の別のロガーを作成します。
最後に、階層を示すために、各コンテキストで2つのメッセージをログに記録します。 ログバックは、WARNおよびINFOメッセージをログに記録し、 DEBUG メッセージをフィルタリングします。
次に、ルートロガーを使用しましょう。
ch.qos.logback.classic.Logger logger =
(ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.baeldung.logback");
logger.debug("Hi there!");
Logger rootLogger =
(ch.qos.logback.classic.Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
logger.debug("This message is logged because DEBUG == DEBUG.");
rootLogger.setLevel(Level.ERROR);
logger.warn("This message is not logged because WARN < ERROR.");
logger.error("This is logged.");
このスニペットを実行すると、次のメッセージが表示されます。
20:44:44.241 [main] DEBUG com.baeldung.logback - Hi there!
20:44:44.243 [main] DEBUG com.baeldung.logback - This message is logged because DEBUG == DEBUG.
20:44:44.243 [main] ERROR com.baeldung.logback - This is logged.
要約すると、 Logger コンテキストから始めて、DEBUGメッセージを出力しました。
次に、静的に定義された名前を使用してルートロガーを取得し、そのレベルをERRORに設定しました。
最後に、Logbackが実際にエラー未満のステートメントをフィルタリングすることを示しました。
5.3. パラメータ化されたメッセージ
上記のサンプルスニペットのメッセージとは異なり、最も有用なログメッセージでは、文字列を追加する必要があります。これには、メモリの割り当て、オブジェクトのシリアル化、文字列の連結が必要であり、後でガベージをクリーンアップする可能性があります。
次のメッセージについて考えてみます。
log.debug("Current count is " + count);
Logger がメッセージをログに記録するかどうかに関係なく、メッセージの作成にかかる費用が発生します。
Logbackは、パラメータ化されたメッセージで代替手段を提供します。
log.debug("Current count is {}", count);
中括弧{}は、任意の Object を受け入れ、その toString()メソッドを使用して、ログメッセージが必要であることを確認した後にのみメッセージを作成します。
いくつかの異なるパラメータを試してみましょう。
String message = "This is a String";
Integer zero = 0;
try {
logger.debug("Logging message: {}", message);
logger.debug("Going to divide {} by {}", 42, zero);
int result = 42 / zero;
} catch (Exception e) {
logger.error("Error dividing {} by {} ", 42, zero, e);
}
このスニペットは次のようになります。
21:32:10.311 [main] DEBUG com.baeldung.logback.LogbackTests - Logging message: This is a String
21:32:10.316 [main] DEBUG com.baeldung.logback.LogbackTests - Going to divide 42 by 0
21:32:10.316 [main] ERROR com.baeldung.logback.LogbackTests - Error dividing 42 by 0
java.lang.ArithmeticException: / by zero
at com.baeldung.logback.LogbackTests.givenParameters_ValuesLogged(LogbackTests.java:64)
...
String、、 int、、およびIntegerをパラメーターとして渡す方法を確認します。
また、 Exception がloggingメソッドの最後の引数として渡されると、Logbackはスタックトレースを出力します。
6. 詳細な構成
前の例では、セクション4 で作成した11行の構成ファイルを使用して、ログメッセージをコンソールに出力していました。 これはLogbackのデフォルトの動作です。 構成ファイルが見つからない場合は、 ConsoleAppender を作成し、ルートロガーに関連付けます。
6.1. 構成情報の検索
構成ファイルはクラスパスに配置でき、logback.xmlまたはlogback-test.xml。のいずれかの名前を付けることができます。
Logbackが構成データを検索する方法は次のとおりです。
- クラスパスでlogback-test.xml 、logback.groovy、 、またはlogback.xmlという名前のファイルをこの順序で検索します
- ライブラリがこれらのファイルを見つけられない場合、ライブラリはJavaの ServiceLoader を使用して、com.qos.logback.classic.spi.Configurator。の実装者を見つけようとします。 ]
- 出力をコンソールに直接記録するように自分自身を構成します
注:Java 9と互換性のあるバージョンのGroovyがないため、現在のバージョンのLogbackはGroovy構成をサポートしていません。
6.2. 基本構成
ファイル全体が
タイプConsoleAppenderのAppenderを宣言し、STDOUTという名前のタグが表示されます。 そのタグ内にネストされているのはエンコーダーです。 sprintf-styleエスケープコードのようなパターンがあります。
<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タグが表示されます。 このタグは、ルートロガーを DEBUG モードに設定し、その出力をSTDOUTという名前のAppenderに関連付けます。
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
6.3. 構成のトラブルシューティング
ログバック構成ファイルは複雑になる可能性があるため、トラブルシューティングのための組み込みメカニズムがいくつかあります。
Logbackが構成を処理するときにデバッグ情報を表示するには、デバッグログをオンにします。
<configuration debug="true">
...
</configuration>
Logbackは、構成を処理するときにステータス情報をコンソールに出力します。
23:54:23,040 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml]
at [file:/Users/egoebelbecker/ideaProjects/logback-guide/out/test/resources/logback-test.xml]
23:54:23,230 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender
of type [ch.qos.logback.core.ConsoleAppender]
23:54:23,236 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
23:54:23,247 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type
[ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
23:54:23,308 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
23:54:23,309 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
23:54:23,310 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
23:54:23,313 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@5afa04c - Registering current configuration
as safe fallback point
構成ファイルの解析中に警告またはエラーが発生した場合、Logbackはステータスメッセージをコンソールに書き込みます。
ステータス情報を印刷するための2番目のメカニズムがあります。
<configuration>
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
...
</configuration>
StatusListenerはステータスメッセージをインターセプトし、構成中およびプログラムの実行中にそれらを出力します。
すべての構成ファイルからの出力が出力されるため、クラスパス上の「不正な」構成ファイルを見つけるのに役立ちます。
6.4. 構成を自動的に再ロードする
アプリケーションの実行中にロギング構成を再ロードすることは、強力なトラブルシューティングツールです。 ログバックは、scanパラメーターでこれを可能にします。
<configuration scan="true">
...
</configuration>
デフォルトの動作では、構成ファイルをスキャンして60秒ごとに変更を確認します。 scanPeriod を追加することで、この間隔を変更できます。
<configuration scan="true" scanPeriod="15 seconds">
...
</configuration>
値は、ミリ秒、秒、分、または時間で指定できます。
6.5. ロガーの変更
上記のサンプルファイルでは、ルートロガーのレベルを設定し、コンソールAppenderに関連付けています。
任意のロガーのレベルを設定できます。
<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>
<logger name="com.baeldung.logback" level="INFO" />
<logger name="com.baeldung.logback.tests" level="WARN" />
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
これをクラスパスに追加して、コードを実行してみましょう。
Logger foobar =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.baeldung.foobar");
Logger logger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.baeldung.logback");
Logger testslogger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.baeldung.logback.tests");
foobar.debug("This is logged from foobar");
logger.debug("This is not logged from logger");
logger.info("This is logged from logger");
testslogger.info("This is not logged from tests");
testslogger.warn("This is logged from tests");
次の出力が表示されます。
00:29:51.787 [main] DEBUG com.baeldung.foobar - This is logged from foobar
00:29:51.789 [main] INFO com.baeldung.logback - This is logged from logger
00:29:51.789 [main] WARN com.baeldung.logback.tests - This is logged from tests
ロガーのレベルをプログラムで設定しないことにより、構成によってそれらが設定されます。 com.baeldung.foobarはルートロガーからDEBUGを継承します。
ロガーは、ルートロガーからappender-refも継承します。 以下に示すように、これをオーバーライドできます。
6.6. 可変置換
ログバック構成ファイルは変数をサポートします。 構成スクリプト内または外部で変数を定義します。 変数は、値の代わりに構成スクリプトの任意の時点で指定できます。
たとえば、FileAppenderの構成は次のとおりです。
<property name="LOG_DIR" value="/var/log/application" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOG_DIR}/tests.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
構成の上部で、プロパティという名前のLOG_DIR。を宣言し、ファイルへのパスの一部として使用しました。 appender定義内。
プロパティはで宣言されます
$ java -DLOG_DIR=/var/log/application com.baeldung.logback.LogbackTests
プロパティの値は${propertyname}で指定します。ログバックは、テキスト置換として変数を実装します。 変数の置換は、値を指定できる構成ファイルの任意の時点で発生する可能性があります。
7. アペンダー
LoggersはLoggingEventsをAppendersに渡します。Appendersは実際のロギング作業を行います。 通常、ロギングはファイルまたはコンソールに送信されるものと考えられますが、Logbackにはさらに多くの機能があります。 Logback-core は、いくつかの便利なappendersを提供します。
7.1. ConsoleAppender
ConsoleAppender の動作はすでに確認済みです。 その名前にもかかわらず、ConsoleAppenderはSystem.outまたはSystem.err。にメッセージを追加します
OutputStreamWriterを使用してI/Oをバッファリングするため、 System.err に転送しても、バッファリングされていない書き込みは発生しません。
7.2. FileAppender
FileAppender メッセージをファイルに追加します。 幅広い構成パラメーターをサポートします。 基本構成にファイルappenderを追加しましょう。
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>tests.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.baeldung.logback" level="INFO" />
<logger name="com.baeldung.logback.tests" level="WARN">
<appender-ref ref="FILE" />
</logger>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
The FileAppender を介してファイル名で構成されます
上からテストを再実行すると、 com.baeldung.logback.tests コンソールとtests.logという名前のファイルの両方に移動します。
この動作をオーバーライドできます。
<logger name="com.baeldung.logback.tests" level="WARN" additivity="false" >
<appender-ref ref="FILE" />
</logger>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
additivityをfalse に設定すると、デフォルトの動作が無効になります。 Tests はコンソールにログを記録せず、その子孫もログに記録しません。
7.3. RollingFileAppender
多くの場合、同じファイルにログメッセージを追加することは、必要な動作ではありません。 時間、ログファイルのサイズ、またはその両方の組み合わせに基づいてファイルを「ロール」する必要があります。
このために、 RollingFileAppender:があります
<property name="LOG_FILE" value="LogFile" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
RollingFileAppender にはRollingPolicyがあります。このサンプル構成では、TimeBasedRollingPolicy。
FileAppender、と同様に、このappenderをファイル名で構成しました。 以下のファイル名を再利用するため、プロパティを宣言して使用しました。
RollingPolicy内にfileNamePatternを定義しました。このパターンは、ファイルの名前だけでなく、ファイルをロールする頻度も定義します。 TimeBasedRollingPolicy はパターンを調べ、最も細かく定義された期間でロールします。
例えば:
<property name="LOG_FILE" value="LogFile" />
<property name="LOG_DIR" value="/var/logs/application" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${LOG_FILE}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/%d{yyyy/MM}/${LOG_FILE}.gz</fileNamePattern>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
アクティブなログファイルは/var/logs/application/LogFileです。このファイルは、毎月初めに/現在の年/現在の月/LogFile.gzにロールオーバーされます。 およびRollingFileAppenderは、新しいアクティブファイルを作成します。
アーカイブファイルの合計サイズが3GBに達すると、 RollingFileAppender は先入れ先出し法でアーカイブを削除します。
週、時間、分、秒、さらにはミリ秒のコードがあります。 ログバックにはここの参照があります。
RollingFileAppender には、ファイルの圧縮のサポートも組み込まれています。 LogFile.gz。という名前を付けたため、ロールされたファイルが圧縮されます。
TimeBasedPolicy は、ファイルをローリングするための唯一のオプションではありません。 Logbackは、 SizeAndTimeBasedRollingPolicy、 も提供します。これは、現在のログファイルのサイズと時間に基づいてロールします。 また、 FixedWindowRollingPolicy、 も提供しており、ロガーが起動するたびにログファイル名をロールします。
独自のRollingPolicyを作成することもできます。
7.4. カスタムアペンダー
Logbackの基本appenderクラスの1つを拡張することにより、カスタムappendersを作成できます。 カスタムアペンダーここを作成するためのチュートリアルがあります。
8. レイアウト
レイアウト形式のログメッセージ。 他のログバックと同様に、レイアウト は拡張可能であり、独自に作成できます。ただし、デフォルトの PatternLayout は、ほとんどのアプリケーションに必要なものを提供しますそしてその後、いくつかの。
これまでのすべての例でPatternLayoutを使用しました。
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
この構成スクリプトには、PatternLayoutEncoderの構成が含まれています。 エンコーダーをアペンダー、およびこのエンコーダーに渡しますPatternLayoutを使用してメッセージをフォーマットします。
のテキスト
これを分解してみましょう。 PatternLayout は%を含む変換ワードを認識するため、パターン内の変換は以下を生成します。
- %d {HH:mm:ss.SSS} –時間、分、秒、ミリ秒のタイムスタンプ
- [%thread] –ログメッセージを生成するスレッド名。角かっこで囲まれています
- %-5le vel –ログイベントのレベル。5文字で埋められます
- %lo gger {36} –ロガーの名前。35文字に切り捨てられます
- %msg%n –ログメッセージの後にプラットフォームに依存する行区切り文字
したがって、次のようなメッセージが表示されます。
21:32:10.311 [main] DEBUG com.baeldung.logback.LogbackTests - Logging message: This is a String
変換ワードとフォーマット修飾子の完全なリストは、ここにあります。
9. 結論
この広範な記事では、アプリケーションでLogbackを使用するための基本について説明しました。
Logbackのアーキテクチャの3つの主要コンポーネントであるLogger、 Appender 、およびLayoutを確認しました。 Logbackには強力な構成スクリプトがあり、メッセージのフィルタリングとフォーマットのためにコンポーネントを操作するために使用しました。 また、ログファイルを作成、ロールオーバー、整理、および圧縮するために最も一般的に使用される2つのファイルアペンダーについても説明しました。
いつものように、コードスニペットはGitHubのにあります。