20.4. 詳細設定
20.4.1. SIFT ロギング
Fuse-Karaf は、$FUSE_HOME/etc/org.ops4j.pax.logging.cfg ファイルで、Log4j2 sift アペンダーの設定例 (デフォルトではコメントアウトして除外されている) と、このアペンダーを使用したロガーを提供します。
# Sift appender log4j2.appender.mdc.type = Routing log4j2.appender.mdc.name = SiftAppender log4j2.appender.mdc.routes.type = Routes # see: http://logging.apache.org/log4j/2.x/manual/appenders.html#Routes log4j2.appender.mdc.routes.pattern = $\\{ctx:bundle.name} log4j2.appender.mdc.routes.sift.type = Route log4j2.appender.mdc.routes.sift.appender.type = RollingRandomAccessFile log4j2.appender.mdc.routes.sift.appender.name = RollingFile log4j2.appender.mdc.routes.sift.appender.fileName = ${karaf.data}/log/sift-$\\{ctx:bundle.name}.log log4j2.appender.mdc.routes.sift.appender.filePattern = ${karaf.data}/log/sift-$\\{ctx:bundle.name}-%i.log.gz log4j2.appender.mdc.routes.sift.appender.append = true log4j2.appender.mdc.routes.sift.appender.layout.type = PatternLayout log4j2.appender.mdc.routes.sift.appender.layout.pattern = ${log4j2.pattern} log4j2.appender.mdc.routes.sift.appender.policies.type = Policies log4j2.appender.mdc.routes.sift.appender.policies.size.type = SizeBasedTriggeringPolicy log4j2.appender.mdc.routes.sift.appender.policies.size.size = 16MB log4j2.appender.mdc.routes.sift.appender.strategy.type = DefaultRolloverStrategy log4j2.appender.mdc.routes.sift.appender.strategy.max = 20 ... # sample logger using Sift appender #log4j2.logger.example.name = org.apache.camel #log4j2.logger.example.level = INFO #log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender
この設定は、http://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender で説明されています。
SIFT/Routing アペンダーのパターンプロパティーは、ロギングのターゲットの場所を区別するために使用できます。
さまざまなルックアップを利用できますが、このルックアップについては http://logging.apache.org/log4j/2.x/manual/lookups.html を参照してください。
最も重要なルックアップは ctx で、ThreadContext マップ (MDC とも呼ばれる) の値 (キー) をルックアップします。
Fuse Karaf によって提供されるデフォルト設定は ctx:bundle.name をパターンとして使用します。つまり、以下のようになります。
lookup bundle.name key in MDC
pax-logging 自体が接頭辞の付いたキーを渡します。以下の異なる 3 つ値から選択できます。
- bundle.name == org.osgi.framework.Bundle.getSymbolicName()
- bundle.id == org.osgi.framework.Bundle.getBundleId()
- bundle.version == org.osgi.framework.Bundle.getVersion().toString()
ただし、Camel コンテキストが (Blueprint XML DSL) を使用して MDC サポートで作成されている場合:
<camelContext id="my-context" xmlns="http://camel.apache.org/schema/blueprint" useMDCLogging="true">
MDC/ThreadContext で使用できる鍵は他にもあり、SIFT アペンダー設定のパターンとして使用できます。
- camel.exchangeId - エクスチェンジ ID
- camel.messageId - メッセージ ID
- camel.correlationId: 相関があればエクスチェンジの相関 ID。(例: Splitter EIP のサブメッセージ)。
- camel.transactionKey: トランザクションエクスチェンジのトランザクションの ID。id は一意ではありませんが、指定のトランザクションのトランザクション境界をマークするトランザクションテンプレートの ID であることに注意してください。そのため、このキーに transactionKey という名前を付け、transactionID でこのファクトを参照しないように決定しました。
- camel.routeId - エクスチェンジが現在ルーティングされるルートの ID
- camel.breadcrumbId: トランスポート全体でメッセージを追跡するために使用される一意の ID。
- camel.contextId - 異なる Camel コンテキストからメッセージを追跡するために使用される Camel コンテキスト ID。
https://people.apache.org/~dkulp/camel/mdc-logging.html を参照してください。
たとえば、ロギング宛先ファイルを Camel のルート ID で区別するには、以下を使用します。
log4j2.appender.mdc.routes.pattern = $\\{ctx:camel.routeId} ... log4j2.appender.mdc.routes.sift.appender.fileName = ${karaf.data}/log/sift-$\\{ctx:camel.routeId}.log log4j2.appender.mdc.routes.sift.appender.filePattern = ${karaf.data}/log/sift-$\\{ctx:camel.routeId}-%i.log.gz
また、アペンダーの設定だけでは不十分であるため、一部のロガーに添付する必要があります。ここでも、設定のサンプルには以下が含まれます。
# sample logger using Sift appender #log4j2.logger.example.name = org.apache.camel #log4j2.logger.example.level = INFO #log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender
(log4j2.logger.example.appenderRef.SiftAppender.ref プロパティーの SiftAppender 値は、アペンダー設定の log4j2.appender.mdc.name の値と一致する必要があることに注意してください)。
ここでは、org.apache.camel はロガー名 (またはカテゴリー名) です。これは、Camel のログ: エンドポイントで使用される値と全く同じです。(Camel ルートの場合) の設定は以下のとおりです。
<to uri="log:org.apache.camel" />
ロギングは機能します。
もう 1 つの作業設定は以下のようになります。
<to uri="log:my-special-logger" />
および
log4j2.logger.example.name = my-special-logger log4j2.logger.example.level = DEBUG log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender
20.4.2. フィルター
フィルターはアペンダーに適用できます。フィルターは各ログイベントを評価し、ログに送信するかどうかを決定します。
Log4j2 で、すぐに使用できるフィルターが提供されます。
これらの包括的なビューについては、Log4J サイトの フィルター を参照してください。
20.4.3. ネストされたアペンダー
ネストされたアペンダーは、別のアペンダーを使用する特別な種類のアペンダーです。アペンダーのチェーン間である種のルーティングを設定できます。
最も使用される入れ子に準拠するアペンダーは以下のとおりです。
-
AsyncAppender(
org.apache.log4j2.AsyncAppender
) は、イベントを非同期でログに記録します。このアペンダーはイベントを収集し、それに接続されているすべてのアペンダーにディスパッチします。 -
RewriteAppender (
org.apache.log4j2.rewrite.RewriteAppender
) は、ログイベントを書き直した後、ログイベントを別のアペンダーに転送します。
このアペンダーは、アペンダー定義で appenders
プロパティーを受け入れます。
log4j2.appender.[appender-name].appenders=[comma-separated-list-of-appender-names]
たとえば、async
という名前の AsyncAppender を作成し、ログイベントを JMS アペンダーに非同期にディスパッチできます。
log4j2.appender.async=org.apache.log4j2.AsyncAppender log4j2.appender.async.appenders=jms log4j2.appender.jms=org.apache.log4j2.net.JMSAppender ...
20.4.4. エラーハンドラー
アペンダーが失敗する可能性があります。たとえば、RollingFileAppender
はファイルシステムへの書き込みを試みてもファイルシステムが満杯であったり、JMS アペンダーがメッセージを送信しようとしても JMS ブローカーは利用できない場合などです。
ロギングは極めて重要なので、ログアペンダーに障害があるかどうかを把握することは重要です。
各ログアペンダーはエラー処理をエラーハンドラーに委譲できるため、アペンダーエラーに対応することができます。
-
FailoverAppender (
org.apache.log4j2.varia.FailoverAppender
) を使用すると、プライマリーアペンダーが失敗した場合にセカンダリーアペンダーを引き継ぐことができます。エラーメッセージがSystem.err
で出力され、セカンダリーアペンダーのログに記録されます。
FailoverAppender の詳細は、Log4j2 の Apppender ページ にアクセスしてください。
アペンダー定義自体で errorhandler
プロパティーを使用して、各アペンダーに使用するエラーハンドラーを定義できます。
log4j2.appender.[appender-name].errorhandler=[error-handler-class] log4j2.appender.[appender-name].errorhandler.root-ref=[true|false] log4j2.appender.[appender-name].errorhandler.logger-ref=[logger-ref] log4j2.appender.[appender-name].errorhandler.appender-ref=[appender-ref]
20.4.5. OSGi 固有の MDC 属性
routing
アペンダーは、MDC (Mapped Diagnostic Context) 属性に基づいてログイベントの分割を可能にする OSGi 指向アペンダーです。
MDC では、ログイベントのさまざまなソースを区別できます。
routing
アペンダーは、デフォルトで OSGi 指向の MDC 属性を提供します。
-
bundle.id
はバンドル ID です -
bundle.name
は、バンドルのシンボリック名です。 -
bundle.version
はバンドルバージョンです
以下の MDC プロパティーを使用すると、バンドルごとにログファイルを作成できます。
log4j2.appender.routing.type = Routing log4j2.appender.routing.name = Routing log4j2.appender.routing.routes.type = Routes log4j2.appender.routing.routes.pattern = $$\\{ctx:bundle.name\\} log4j2.appender.routing.routes.bundle.type = Route log4j2.appender.routing.routes.bundle.appender.type = RollingRandomAccessFile log4j2.appender.routing.routes.bundle.appender.name = Bundle-$\\{ctx:bundle.name\} log4j2.appender.routing.routes.bundle.appender.fileName = ${karaf.data}/log/bundle-$\\{ctx:bundle.name\\}.log log4j2.appender.routing.routes.bundle.appender.filePattern = ${karaf.data}/log/bundle-$\\{ctx:bundle.name\\}.log.%d{yyyy-MM-dd} log4j2.appender.routing.routes.bundle.appender.append = true log4j2.appender.routing.routes.bundle.appender.layout.type = PatternLayout log4j2.appender.routing.routes.bundle.appender.policies.type = Policies log4j2.appender.routing.routes.bundle.appender.policies.time.type = TimeBasedTriggeringPolicy log4j2.appender.routing.routes.bundle.appender.strategy.type = DefaultRolloverStrategy log4j2.appender.routing.routes.bundle.appender.strategy.max = 31 log4j2.rootLogger.appenderRef.Routing.ref = Routing
20.4.6. OSGi スタックトレースレンダラーの強化
デフォルトでは、Apache Karaf は特殊なスタックトレースレンダラーを提供し、OSGi 固有の情報を追加します。
スタックトレースでは、例外を出力するクラスに加えて、各スタックトレース行の末尾にある [id:name:version]
パターンを見つけることができます。
-
id
はバンドル ID です -
name
はバンドル名です -
version
はバンドルバージョンです
問題源を診断すると非常に役立ちます。
たとえば、以下の IllegalArgumentException スタックトレースでは、例外のソースに関する OSGi の詳細を確認できます。
java.lang.IllegalArgumentException: Command not found: *:foo at org.apache.felix.gogo.runtime.shell.Closure.execute(Closure.java:225)[21:org.apache.karaf.shell.console:4.0.0] at org.apache.felix.gogo.runtime.shell.Closure.executeStatement(Closure.java:162)[21:org.apache.karaf.shell.console:4.0.0] at org.apache.felix.gogo.runtime.shell.Pipe.run(Pipe.java:101)[21:org.apache.karaf.shell.console:4.0.0] at org.apache.felix.gogo.runtime.shell.Closure.execute(Closure.java:79)[21:org.apache.karaf.shell.console:4.0.0] at org.apache.felix.gogo.runtime.shell.CommandSessionImpl.execute(CommandSessionImpl.java:71)[21:org.apache.karaf.shell.console:4.0.0] at org.apache.karaf.shell.console.jline.Console.run(Console.java:169)[21:org.apache.karaf.shell.console:4.0.0] at java.lang.Thread.run(Thread.java:637)[:1.7.0_21]
20.4.7. カスタムアペンダー
Apache Karaf で独自のアペンダーを使用できます。
これを行う最も簡単な方法は、アペンダーを OSGi バンドルとしてパッケージ化し、org.ops4j.pax.logging.pax-logging-service
バンドルのフラグメントとしてアタッチすることです。
たとえば、MyAppender
を作成します。
public class MyAppender extends AppenderSkeleton { ... }
MANIFEST を含む OSGi バンドルとしてコンパイルしてパッケージ化すると以下のようになります。
Manifest: Bundle-SymbolicName: org.mydomain.myappender Fragment-Host: org.ops4j.pax.logging.pax-logging-service ...
Apache Karaf system
フォルダーでバンドルをコピーします。system
フォルダーは、標準の Maven ディレクトリーレイアウト groupId/artifactId/version を使用します。
etc/startup.properties
設定ファイルで、pax-logging-service バンドルの前にバンドルをリストで定義します。
システムバンドルをリロードするには、クリーンな実行 (data
フォルダーのパージ) で Apache Karaf を再起動する必要があります。これで、etc/org.ops4j.pax.logging.cfg
設定ファイルでアペンダーを直接使用できるようになります。