第18章 Maven Indexer プラグイン

Maven プラグインがアーティファクトに対して Maven Central を迅速に検索できるようにするには、Maven Indexer プラグインが必要です。

Maven Indexer プラグインをデプロイするには、以下のコマンドを使用します。

前提条件

Maven Indexer プラグインをデプロイする前に、Installing on Apache Karaf の Preparing to Use Maven セクションの手順に従うようにしてください。

Maven Indexer プラグインのデプロイ

  1. Karaf コンソールに移動し、以下のコマンドを実行して Maven Indexer プラグインをインストールします。

    features:install hawtio-maven-indexer
  2. 以下のコマンドを入力して Maven Indexer プラグインを設定します。

    config:edit io.hawt.maven.indexer
    config:proplist
    config:propset repositories 'https://maven.oracle.com'
    config:proplist
    config:update
  3. Maven Indexer プラグインがデプロイされるまで待ちます。これには数分の時間がかかる場合があります。以下のようなメッセージがログタブに表示されます。

    maven indexer ログ

Maven Indexer プラグインがデプロイされると、以下のコマンドを使用して追加の外部 Maven リポジトリーを Maven Indexer プラグイン設定に追加します。

config:edit io.hawt.maven.indexer
config:proplist
config:propset repositories external repository
config:proplist
config:update

18.1. Log

Apache Karaf は、動的で強力なロギングシステムを提供します。

以下をサポートします。

  • OSGi ログサービス
  • Apache Log4j v1 および v2 フレームワーク
  • Apache Commons Logging フレームワーク
  • Logback フレームワーク
  • SLF4J フレームワーク
  • ネイティブ Java Util Logging フレームワーク

つまり、アプリケーションはすべてのロギングフレームワークを使用でき、Apache Karaf は中央のログシステムを使用してロガーやアペンダーなどを管理できます。

18.1.1. 設定ファイル

初期ログ設定は、etc/org.ops4j.pax.logging.cfg からロードされます。

このファイルは 標準の Log4j2 設定ファイル です。

さまざまな Log4j2 要素があります。

  • loggers
  • アペンダー
  • レイアウト

独自の初期設定を直接ファイルに追加できます。

デフォルト設定は以下のとおりです。

#
#  Copyright 2005-2018 Red Hat, Inc.
#
#  Red Hat licenses this file to you under the Apache License, version
#  2.0 (the "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
#  implied.  See the License for the specific language governing
#  permissions and limitations under the License.
#

#
# Internal Log4j2 configuration
#
log4j2.status = WARN
log4j2.verbose = false
log4j2.dest = out

#
# Common pattern layouts for appenders defined as reusable properties
# See https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout
# references will be replaced by felix.fileinstall
#
log4j2.pattern = %d{DEFAULT} | %-5.5p | %-20.20t | %-32.32c{1.} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n
#log4j2.pattern = %d{DEFAULT} %-5.5p {%t} [%C.%M()] (%F:%L) : %m%n

#
# Appenders configuration
#

# JDBC Appender
log4j2.appender.jdbc.type = JDBC
log4j2.appender.jdbc.name = JdbcAppender
log4j2.appender.jdbc.tableName = EVENTS
log4j2.appender.jdbc.cs.type = DataSource
log4j2.appender.jdbc.cs.lazy = true
log4j2.appender.jdbc.cs.jndiName = osgi:service/jdbc/logdb
log4j2.appender.jdbc.c1.type = Column
log4j2.appender.jdbc.c1.name = DATE
log4j2.appender.jdbc.c1.isEventTimestamp = true
log4j2.appender.jdbc.c2.type = Column
log4j2.appender.jdbc.c2.name = LEVEL
log4j2.appender.jdbc.c2.pattern = %level
log4j2.appender.jdbc.c2.isUnicode = false
log4j2.appender.jdbc.c3.type = Column
log4j2.appender.jdbc.c3.name = SOURCE
log4j2.appender.jdbc.c3.pattern = %logger
log4j2.appender.jdbc.c3.isUnicode = false
log4j2.appender.jdbc.c4.type = Column
log4j2.appender.jdbc.c4.name = THREAD_ID
log4j2.appender.jdbc.c4.pattern = %thread
log4j2.appender.jdbc.c4.isUnicode = false
log4j2.appender.jdbc.c5.type = Column
log4j2.appender.jdbc.c5.name = MESSAGE
log4j2.appender.jdbc.c5.pattern = %message
log4j2.appender.jdbc.c5.isUnicode = false


# Console appender not used by default (see log4j2.rootLogger.appenderRefs)
log4j2.appender.console.type = Console
log4j2.appender.console.name = Console
log4j2.appender.console.layout.type = PatternLayout
log4j2.appender.console.layout.pattern = ${log4j2.pattern}

# Rolling file appender
log4j2.appender.rolling.type = RollingRandomAccessFile
log4j2.appender.rolling.name = RollingFile
log4j2.appender.rolling.fileName = ${karaf.data}/log/fuse.log
log4j2.appender.rolling.filePattern = ${karaf.data}/log/fuse-%i.log.gz
# uncomment to not force a disk flush
#log4j2.appender.rolling.immediateFlush = false
log4j2.appender.rolling.append = true
log4j2.appender.rolling.layout.type = PatternLayout
log4j2.appender.rolling.layout.pattern = ${log4j2.pattern}
log4j2.appender.rolling.policies.type = Policies
log4j2.appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
log4j2.appender.rolling.policies.size.size = 16MB
log4j2.appender.rolling.strategy.type = DefaultRolloverStrategy
log4j2.appender.rolling.strategy.max = 20

# Audit file appender
log4j2.appender.audit.type = RollingRandomAccessFile
log4j2.appender.audit.name = AuditRollingFile
log4j2.appender.audit.fileName = ${karaf.data}/security/audit.log
log4j2.appender.audit.filePattern = ${karaf.data}/security/audit.log.%i
log4j2.appender.audit.append = true
log4j2.appender.audit.layout.type = PatternLayout
log4j2.appender.audit.layout.pattern = ${log4j2.pattern}
log4j2.appender.audit.policies.type = Policies
log4j2.appender.audit.policies.size.type = SizeBasedTriggeringPolicy
log4j2.appender.audit.policies.size.size = 8MB

# OSGi appender
log4j2.appender.osgi.type = PaxOsgi
log4j2.appender.osgi.name = PaxOsgi
log4j2.appender.osgi.filter = *

#
# Loggers configuration
#

# Root logger
log4j2.rootLogger.level = INFO
log4j2.rootLogger.appenderRef.RollingFile.ref = RollingFile
log4j2.rootLogger.appenderRef.PaxOsgi.ref = PaxOsgi
log4j2.rootLogger.appenderRef.Console.ref = Console
log4j2.rootLogger.appenderRef.Console.filter.threshold.type = ThresholdFilter
log4j2.rootLogger.appenderRef.Console.filter.threshold.level = ${karaf.log.console:-OFF}
#log4j2.rootLogger.appenderRef.Sift.ref = Routing

# Spifly logger
log4j2.logger.spifly.name = org.apache.aries.spifly
log4j2.logger.spifly.level = WARN

# Security audit logger
log4j2.logger.audit.name = org.apache.karaf.jaas.modules.audit
log4j2.logger.audit.level = INFO
log4j2.logger.audit.additivity = false
log4j2.logger.audit.appenderRef.AuditRollingFile.ref = AuditRollingFile

# help with identification of maven-related problems with pax-url-aether
#log4j2.logger.aether.name = shaded.org.eclipse.aether
#log4j2.logger.aether.level = TRACE
#log4j2.logger.http-headers.name = shaded.org.apache.http.headers
#log4j2.logger.http-headers.level = DEBUG
#log4j2.logger.maven.name = org.ops4j.pax.url.mvn
#log4j2.logger.maven.level = TRACE

デフォルト設定では、out ファイルアペンダーを使用して、INFO ログレベルで ROOT ロガーを定義します。ログレベルは、Log4j2 の有効な値に変更できます。最も詳細度の低いものから高いものまで、TRACE、DEBUG、INFO、ERROR、または FATAL を指定できます。

OSGi アペンダー
osgi:* アペンダーは、ログメッセージを OSGi Log Service に送信する特別なアペンダーです。
stdout アペンダー
stdout コンソールアペンダーは事前設定されていますが、デフォルトでは有効になっていません。このアペンダーを使用すると、ログメッセージを標準出力に直接表示できます。サーバーモードで Apache Karaf を実行する予定 (コンソールなし) の場合は便利です。

有効にするには、stdout アペンダーを rootLogger に追加する必要があります。

log4j2.rootLogger=INFO, out, stdout, osgi:*
out アペンダー
out アペンダーは、デフォルトのアペンダーです。これは、1MB ログファイル 10 個を管理してローテーションするローリングファイルアペンダーです。ログファイルはデフォルトで data/log/fuse.log にあります。
SIFT アペンダー
sift アペンダーは、デフォルトでは有効になっていません。このアペンダーを使用すると、デプロイされたバンドルごとに 1 つのログファイルを作成することができます。デフォルトでは、ログファイルの名前の形式は、バンドルのシンボリック名 (data/log フォルダーの) を使用します。このファイルはランタイム時に編集できます。Apache Karaf はファイルを再読み込みし、変更を有効にします。Apache Karaf を再起動する必要はありません。別の設定ファイルは Apache Karaf により使用されます (etc/org.apache.karaf.log.cfg)。このファイルは、ログコマンドによって使用されるログサービスを設定します (後で参照してください)。
JDBC アペンダー
jdbc アペンダーには lazy フラグがあり、true (有効) で、データソースが利用できない場合は、ロギングはデータベースに追加されません。ただし、jndi、データソース、または接続が戻ると、ロギングが再起動されます。
log4j2.appender.jdbc.cs.lazy = true
重要

ログメッセージが失われないようにするには、緊急アペンダーを設定することもできます。

18.1.2. コマンド

Apache Karaf は、etc/org.ops4j.pax.logging.cfg ファイルを変更する代わりに、ログ設定を動的に変更してログの内容を確認できる一連のコマンドを提供します。

18.1.2.1. log:clear

log:clear コマンドはログエントリーを消去します。

18.1.2.2. log:display

log:display コマンドは、ログエントリーを表示します。

デフォルトでは、rootLogger のログエントリーが表示されます。

karaf@root()> log:display
2015-07-01 19:12:46,208 | INFO  | FelixStartLevel  | SecurityUtils                    | 16 - org.apache.sshd.core - 0.12.0 | BouncyCastle not registered, using the default JCE provider
2015-07-01 19:12:47,368 | INFO  | FelixStartLevel  | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Starting JMX OSGi agent

logger 引数を使用して、特定のロガーからログエントリーを表示することもできます。

karaf@root()> log:display ssh
2015-07-01 19:12:46,208 | INFO  | FelixStartLevel  | SecurityUtils                    | 16 - org.apache.sshd.core - 0.12.0 | BouncyCastle not registered, using the default JCE provider

デフォルトでは、すべてのログエントリーが表示されます。Apache Karaf コンテナーが長時間にわたる場合には、非常に長い時間がかかる可能性があります。-n オプションを使用して、表示するエントリー数を制限することができます。

karaf@root()> log:display -n 5
2015-07-01 06:53:24,143 | INFO  | JMX OSGi Agent   | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Registering org.osgi.jmx.framework.BundleStateMBean to MBeanServer com.sun.jmx.mbeanserver.JmxMBeanServer@27cc75cb with name osgi.core:type=bundleState,version=1.7,framework=org.apache.felix.framework,uuid=5335370f-9dee-449f-9b1c-cabe74432ed1
2015-07-01 06:53:24,150 | INFO  | JMX OSGi Agent   | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Registering org.osgi.jmx.framework.PackageStateMBean to MBeanServer com.sun.jmx.mbeanserver.JmxMBeanServer@27cc75cb with name osgi.core:type=packageState,version=1.5,framework=org.apache.felix.framework,uuid=5335370f-9dee-449f-9b1c-cabe74432ed1
2015-07-01 06:53:24,150 | INFO  | JMX OSGi Agent   | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Registering org.osgi.jmx.framework.ServiceStateMBean to MBeanServer com.sun.jmx.mbeanserver.JmxMBeanServer@27cc75cb with name osgi.core:type=serviceState,version=1.7,framework=org.apache.felix.framework,uuid=5335370f-9dee-449f-9b1c-cabe74432ed1
2015-07-01 06:53:24,152 | INFO  | JMX OSGi Agent   | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Registering org.osgi.jmx.framework.wiring.BundleWiringStateMBean to MBeanServer com.sun.jmx.mbeanserver.JmxMBeanServer@27cc75cb with name osgi.core:type=wiringState,version=1.1,framework=org.apache.felix.framework,uuid=5335370f-9dee-449f-9b1c-cabe74432ed1
2015-07-01 06:53:24,501 | INFO  | FelixStartLevel  | RegionsPersistenceImpl           | 78 - org.apache.karaf.region.persist - 4.0.0 | Loading region digraph persistence

etc/org.apache.karaf.log.cfg ファイルの size プロパティーを使用すると、保存され保持されるエントリーの数を制限することもできます。

#
# The number of log statements to be displayed using log:display. It also defines the number
# of lines searched for exceptions using log:display exception. You can override this value
# at runtime using -n in log:display.
#
size = 500

デフォルトでは、各ログレベルは異なる色で表示されます。ERROR/FATAL は赤色で、DEBUG は 紫、INFO は水色などで表示されます。--no-color オプションを使用して色付けを無効にすることができます。

ログエントリーの形式パターンは、etc/org.ops4j.pax.logging.cfg ファイルに定義された変換パターンを使用しません。デフォルトでは、etc/org.apache.karaf.log.cfg で定義されている pattern プロパティーを使用します。

#
# The pattern used to format the log statement when using log:display. This pattern is according
# to the log4j2 layout. You can override this parameter at runtime using log:display with -p.
#
pattern = %d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n

-p オプションを使用して、パターンを動的に変更することもできます (1 回の実行)。

karaf@root()> log:display -p "\%d - \%c - \%m\%n"
2015-07-01 07:01:58,007 - org.apache.sshd.common.util.SecurityUtils - BouncyCastle not registered, using the default JCE provider
2015-07-01 07:01:58,725 - org.apache.aries.jmx.core - Starting JMX OSGi agent
2015-07-01 07:01:58,744 - org.apache.aries.jmx.core - Registering MBean with ObjectName [osgi.compendium:service=cm,version=1.3,framework=org.apache.felix.framework,uuid=6361fc65-8df4-4886-b0a6-479df2d61c83] for service with service.id [13]
2015-07-01 07:01:58,747 - org.apache.aries.jmx.core - Registering org.osgi.jmx.service.cm.ConfigurationAdminMBean to MBeanServer com.sun.jmx.mbeanserver.JmxMBeanServer@27cc75cb with name osgi.compendium:service=cm,version=1.3,framework=org.apache.felix.framework,uuid=6361fc65-8df4-4886-b0a6-479df2d61c83

このパターンは通常の Log4j2 パターンで、日付に %d、クラスに %c、ログメッセージに %m などのキーワードを使用できます。

18.1.2.3. log:exception-display

log:exception-display コマンドは、最後に発生した例外を表示します。

log:display コマンドの場合、log:exception-display コマンドはデフォルトで rootLogger を使用しますが、logger 引数を使用してロガーを指定できます。

18.1.2.4. log:get

log:get コマンドは、ロガーの現在のログレベルを表示します。

デフォルトでは、表示されるログレベルはルートロガーからのログレベルです。

karaf@root()> log:get
Logger                              │ Level
────────────────────────────────────┼──────
ROOT                                │ INFO
org.apache.aries.spifly             │ WARN
org.apache.karaf.jaas.modules.audit │ INFO
org.apache.sshd                     │ INFO

logger 引数を使用して、特定のロガーを指定できます。

karaf@root()> log:get ssh
INFO

logger 引数は、ALL キーワードを受け入れて、(リストとして) すべてのロガーのログレベルを表示します。

たとえば、etc/org.ops4j.pax.logging.cfg ファイルに独自のロガーを次のように定義します。

log4j2.logger.my.name = MyLogger
log4j2.logger.my.level = DEBUG

ロガーのリストは、対応するログレベルで確認できます。

karaf@root()> log:get ALL
Logger                              │ Level
────────────────────────────────────┼──────
MyLogger                            │ DEBUG
ROOT                                │ INFO
org.apache.aries.spifly             │ WARN
org.apache.karaf.jaas.modules.audit │ INFO
org.apache.sshd                     │ INFO

log:list コマンドは、log:get ALL のエイリアスです。

18.1.2.5. log:log

log:log コマンドを使用すると、ログにメッセージを手動で追加できます。Apache Karaf スクリプトを作成する場合には、以下が役立ちます。

karaf@root()> log:log "Hello World"
karaf@root()> log:display
12:55:21.706 INFO [pipe-log:log "Hello World"] Hello World

デフォルトでは、ログレベルは INFO ですが、-l オプションを使用して別のログレベルを指定できます。

karaf@root()> log:clear
karaf@root()> log:log -l ERROR "Hello World"
karaf@root()> log:display
12:55:41.460 ERROR [pipe-log:log "Hello World"] Hello World

18.1.2.6. log:set

log:set コマンドは、ロガーのログレベルを設定します。

デフォルトでは、rootLogger のログレベルが変更されます。

karaf@root()> log:set DEBUG
karaf@root()> log:get
Logger                              │ Level
────────────────────────────────────┼──────
ROOT                                │ DEBUG
...

level の後に logger 引数を使用して、特定のロガーを指定できます。

karaf@root()> log:set INFO my.logger
karaf@root()> log:get my.logger
Logger    | Level
-----------------
my.logger | INFO

level 引数は TRACE、DEBUG、INFO、WARN、ERROR、FATAL のいずれかの Log4j2 ログレベルを受け入れます。

また、DEFAULT の特別キーワードも使用できます。

DEFAULT キーワードの目的は、ロガーの現在のレベルを削除して (レベルのみ。アペンダーなどの他のプロパティーは削除されない)、ロガーの親レベル (ロガーは階層的) を使用することです。

たとえば、(etc/org.ops4j.pax.logging.cfg ファイルに) 次のロガーを定義しました。

rootLogger=INFO,out,osgi:*
my.logger=INFO,appender1
my.logger.custom=DEBUG,appender2

my.logger.custom ロガーのレベルを変更できます。

karaf@root()> log:set INFO my.logger.custom

以下のようになります。

rootLogger=INFO,out,osgi:*
my.logger=INFO,appender1
my.logger.custom=INFO,appender2

my.logger.custom ロガーで DEFAULT キーワードを使用して、レベルを削除できます。

karaf@root()> log:set DEFAULT my.logger.custom

以下のようになります。

rootLogger=INFO,out,osgi:*
my.logger=INFO,appender1
my.logger.custom=appender2

つまり、実行時に my.logger.custom ロガーは親 my.logger のレベルを使用するため、INFO となります。

ここで、my.logger ロガーで DEFAULT キーワードを使用するとします。

karaf@root()> log:set DEFAULT my.logger

以下のようになります。

rootLogger=INFO,out,osgi:*
my.logger=appender1
my.logger.custom=appender2

したがって、my.logger.custommy.logger はどちらも、親の rootLogger のログレベルを使用します。

rootLogger で DEFAULT キーワードを使用することはできず、親はありません。

18.1.2.7. log:tail

log:taillog:display と同じですが、ログエントリーが継続的に表示されます。

log:display コマンドと同じオプションと引数を使用できます。

デフォルトでは、rootLogger からのエントリーが表示されます。

karaf@root()> log:tail
2015-07-01 07:40:28,152 | INFO  | FelixStartLevel  | SecurityUtils                    | 16 - org.apache.sshd.core - 0.9.0 | BouncyCastle not registered, using the default JCE provider
2015-07-01 07:40:28,909 | INFO  | FelixStartLevel  | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Starting JMX OSGi agent
2015-07-01 07:40:28,928 | INFO  | FelixStartLevel  | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Registering MBean with ObjectName [osgi.compendium:service=cm,version=1.3,framework=org.apache.felix.framework,uuid=b44a44b7-41cd-498f-936d-3b12d7aafa7b] for service with service.id [13]
2015-07-01 07:40:28,936 | INFO  | JMX OSGi Agent   | core                             | 68 - org.apache.aries.jmx.core - 1.1.1 | Registering org.osgi.jmx.service.cm.ConfigurationAdminMBean to MBeanServer com.sun.jmx.mbeanserver.JmxMBeanServer@27cc75cb with name osgi.compendium:service=cm,version=1.3,framework=org.apache.felix.framework,uuid=b44a44b7-41cd-498f-936d-3b12d7aafa7b

log:tail コマンドから終了するには、CTRL-C を入力します。

18.1.3. JMX LogMBean

log:* コマンドで実行可能なすべてのアクションは、LogMBean を使用して実行できます。

LogMBean オブジェクト名は org.apache.karaf:type=log,name=* です。

18.1.3.1. 属性

  • Level 属性は、ROOT ロガーのレベルです。

18.1.3.2. 操作

  • getLevel(logger) を使用して特定のロガーのログレベルを取得します。この操作は ALL キーワードをサポートするため、各ロガーのレベルで Map を返します。
  • setLevel(level, logger) を使用して特定のロガーのログレベルを取得します。この操作は、log:set コマンドの DEFAULT キーワードをサポートします。

18.1.4. 詳細設定

18.1.4.1. Filters

フィルターはアペンダーに適用できます。フィルターは各ログイベントを評価し、ログに送信するかどうかを決定します。

Log4j2 で、すぐに使用できるフィルターが提供されます。

注記

これらの包括的なビューについては、Log4J サイトの フィルター を参照してください。

18.1.4.2. ネストされたアペンダー

ネストされたアペンダーは、別のアペンダーを使用する特別な種類のアペンダーです。アペンダーのチェーン間である種のルーティングを設定できます。

最も使用される入れ子に準拠するアペンダーは以下のとおりです。

  • 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
...

18.1.4.3. エラーハンドラー

アペンダーが失敗する可能性があります。たとえば、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]

18.1.4.4. OSGi 固有の MDC 属性

routing アペンダーは、MDC (Mapped Diagnostic Context) 属性に基づいてログイベントの分割を可能にする OSGi 指向アペンダーです。

MDC では、ログイベントのさまざまなソースを区別できます。

sift アペンダーは、デフォルトで OSGi 指向の MDC 属性を提供します。

  • bundle.id はバンドル ID です
  • bundle.name は、バンドルのシンボリック名です。
  • bundle.version はバンドルバージョンです

以下の MDC プロパティーを使用すると、バンドルごとにログファイルを作成できます。

#log4j2.rootLogger.appenderRef.Sift.ref = Routing

# Sift - MDC routing
#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.log}/bundle-\$\\\{ctx:bundle.name\}.log
#log4j2.appender.routing.routes.bundle.appender.filePattern = ${karaf.log}/bundle-\$\\\{ctx:bundle.name\}.log.%i
#log4j2.appender.routing.routes.bundle.appender.append = true
#log4j2.appender.routing.routes.bundle.appender.layout.type = PatternLayout
#log4j2.appender.routing.routes.bundle.appender.layout.pattern = ${log4j2.pattern}
#log4j2.appender.routing.routes.bundle.appender.policies.type = Policies
#log4j2.appender.routing.routes.bundle.appender.policies.size.type = SizeBasedTriggeringPolicy
#log4j2.appender.routing.routes.bundle.appender.policies.size.size = 8MB

18.1.4.5. 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]

18.1.4.6. カスタムアペンダー

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 設定ファイルでアペンダーを直接使用できるようになります。