- 印刷する
- PDF
Log4j2 SDK v2 の使用方法
- 印刷する
- PDF
Classic/VPC環境で利用できます。
Log4j2 SDK v2 の使用方法
この章ではEffective Log Search & Analytics log4j2 SDKの使用方法をご説明します。NELOはEffective Log Search & Analyticsのプロジェクトコードネームです。
NELO2 log4j2 SDK dependency の追加
以下のようにDependencyを追加します。
圧縮ファイル解除後、coreモジュールとlog4j2モジュールの経路を
<dependencies>
<dependency>
<groupId>nelo2-java-sdk-core</groupId>
<artifactId>nelo2-java-sdk-core</artifactId>
<version>1.6.6</version>
<scope>system</scope>
<systemPath>/nelo2-java-sdk-core-1.6.6.jar</systemPath>
</dependency>
<dependency>
<groupId>nelo2-java-sdk</groupId>
<artifactId>nelo2-java-sdk-log4j2</artifactId>
<version>2.8.5</version>
<scope>system</scope>
<systemPath>/nelo2-java-sdk-log4j2-2.8.5.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
備考
このSDKはlog4j2のslf4Jバインディングライブラリーであるlog4j-slf4j-implを含めて提供されています。
slf4jは特性上同時に一つのbindingのみサポートするため、他のslf4jバインディングのためのライブラリーを一緒に使ってはいけません。以前使用していた参照ライブラリーとnelo2 log4j2 SDKで参照するライブラリーが重複する場合、問題が発生することがあります。
このような場合はより上位のバージョンを使用されることをお勧めします。
Effective Log Search & Analytics log4j2 appenderの設定及びオプション
以下はEffective Log Search & Analytics log4j2 appenderを含むlog4j2.xmlの設定ファイルの例です。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" shutDownHook="disable">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<ThriftAppender>
<name>nelo</name>
<collectorUrl>COLLECTOR_HOST</collectorUrl>
<port>COLLECTOR_PORT</port>
<projectName>PROJECT_ID</projectName>
<version>PROJECT_VERSION</version>
<logType>LOG_TYPE</logType>
<logSource>LOG_SOURCE</logSource>
</ThriftAppender>
<HttpAppender>
<name>http</name>
<collectorUrl>COLLECTOR_HOST</collectorUrl>
<port>COLLECTOR_PORT</port>
<projectName>PROJECT_ID</projectName>
<version>PROJECT_VERSION</version>
<logType>LOG_TYPE</logType>
<logSource>LOG_SOURCE</logSource>
</HttpAppender>
</Appenders>
<Loggers>
<Logger name="nelo" level="error" additivity="false">
<AppenderRef ref="nelo"/>
<AppenderRef ref="console"/>
</Logger>
<Root level="warn">
<AppenderRef ref="nelo"/>
<AppenderRef ref="console"/>
</Root>
</Loggers>
</Configuration>
オプションは次のような項目を設定できます。
Appender (転送プロトコルに沿ってAppenderのクラス名を選択)
Thrift Appender : ThriftAppender
Http Appender : HttpAppender
projectName: プロジェクトID。Effective Log Search & Analyticsのプロジェクト情報で生成したプロジェクトのIDを確認できます。
version : プロジェクトバージョン(英文字、数字、-, _, .のみ許可されて英文字/数字/_で始まらなければなりません)。
collectorUrl: Effective Log Search & Analytics ログ収集サーバのURL
ThriftAppender: elsa-col.ncloud.com
HttpAppender: http://elsa-col.ncloud.com/_store
port: Collector サーバport
Thrift Appender : 10006
Http Appender : 80
enable: 使用可否(基本値true)
logType : logTypeの設定
logSource : logSourceの設定
errorCodeType: エラーコードタイプ
- default: log4j 基本情報の中、 Exception情報を使用する。Exception情報が送信されなかった場合 (log.error(message)の形式でログが記録される場合)にはエラーメッセージ全体をエラーコードに使用する
例) NullPointerExceptionが発生した場合 => NullPointerException
- default: log4j 基本情報の中、 Exception情報を使用する。Exception情報が送信されなかった場合 (log.error(message)の形式でログが記録される場合)にはエラーメッセージ全体をエラーコードに使用する
message: エラーメッセージの最初から空白文字までのみ使用する
例) ダウンロードエラー ダウンロードに失敗しました。=> ダウンロードエラーmdc: SLF4J MDCの ‘errorCode’ の項目値を設定して使用する。
例)MDC.put(“errorCode”, “Login”) => Logindebug: Effective Log Search & Analyticsのデバッグ情報を表示。基本値はfalse。
このオプションは全域的に適用され、'true'が 'false'に優先されます。つまり、複数のアペンダーが宣言されており、その中の一つのdebug値がtrueの場合、全てのアペンダーでコンソールにデバッグログを出力することになります。
timeout: 送信の際に使用されるsocketのタイムアウト、基本値 5000ms(5秒)
keepAlive: 送信の際に使用されるsocketのkeepAliveタイムアウト、基本値 60000ms(1分), 最大値180000ms(3分)
isBulkEnabled : bulkモードを使用するか否か、基本値 true, falseの場合、各件を個別で送信
bulkSize : bulkモードを使用する場合、1バルクリクエストに送信される最大ログ数、 基本値 1000, 最大値100000
bulkInterval : bulkモードを使用する場合バルク要請を呼び出すことになる周期、デフォルト値1000ms(1秒)、最大値10000ms(10秒)
alwaysIncludeLocation : SDKがすべてのログに Locationフィールドを追加するかどうか、デフォルトはtrueです。
- false : logLevelが ERRORであるログの Locationフィールドを確認および設定します。
- true : すべてのログの Locationフィールドを確認して設定します。 これは、 falseと比較してロギングパフォーマンスに悪影響を与える可能性があります。
mdcConversionRule : MDCキーの名前を変更するためのルール。
- format: key1:newKey1;key2:newkey2;...
例) mdcConversionRuleを time:date;fullname:name に設定します。このルールはMDCキー _time_をdateに、 fullnameが存在する場合はそれらをnameに名前変更します。
- format: key1:newKey1;key2:newkey2;...
bulk/single モード
NELO2 log4j2 SDKはログの転送を1件ずつ送信するsingleモードとまとまった単位で送信する bulkモードをサポートします。
xml appender設定で isBulkEnabledをtrue/falseにしてbulk / singleモードを使用できます(基本値true)。
性能に関するレファレンスはプロトコルに沿って以下の表をご参照ください。
1分間単一スレッドから1kb sizeのログを転送する際のthroughput
- thrift
- single mode: 2636.00 logs/sec
- bulk mode: 6369.10 logs/sec
- http
- single mode: 583.36 logs/sec
- bulk mode: 4618.90 logs/sec
上の性能テストに使用した装備のスペックは以下の通りです。
- ログ転送サーバ: 2GHZ 12core cpu, 48G mem
- ログ収集サーバ: 2.26GHZ 12core cpu, 48G mem
備考
負荷によって転送性能は異なります。
テストは負荷のない状況で実行し、実際に使用中のインスタンスで転送すると比較的低い性能をみせます。
インスタンス負荷による性能の体感はbulkに比べてsinglモードでより大きく現れます。
従って基本値であるbulk モードを使用されることをお勧めします。収集サーバが許可する最大パケットのサイズは30mbです。
クライアントサーバのログパターンを考慮して適切な bulkSizeを設定する必要があります。(基本値 1000)
AsyncAppenderの使用方法
基本的に使用するNeloAppenderに追加でLog4j2でサポートするAsync appenderを使用して実際のログ転送作業を別途のスレッドで実行するように設定できます。
次を参考にして設定します。async appender의 includeLocationはtrueに設定する必要があります。そうでないと送信の際にエラーが発生します。
AsyncAppenderの細部設定に関しては次のlog4j2マニュアルをご参照ください。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" shutDownHook="disable">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<ThriftAppender>
<name>nelo</name>
<collectorUrl>COLLECTOR_HOST</collectorUrl>
<port>COLLECTOR_PORT</port>
<projectName>PROJECT_ID</projectName>
<version>PROJECT_VERSION</version>
<logType>LOG_TYPE</logType>
<logSource>LOG_SOURCE</logSource>
</ThriftAppender>
<HttpAppender>
<name>http</name>
<collectorUrl>COLLECTOR_HOST</collectorUrl>
<port>COLLECTOR_PORT</port>
<projectName>PROJECT_ID</projectName>
<version>PROJECT_VERSION</version>
<logType>LOG_TYPE</logType>
<logSource>LOG_SOURCE</logSource>
</HttpAppender>
<Async name="async">
<AppenderRef ref="nelo"/>
<includeLocation>true</includeLocation>
</Async>
</Appenders>
<Loggers>
<Logger name="nelo" level="error" additivity="false">
<AppenderRef ref="async"/>
<AppenderRef ref="console"/>
</Logger>
<Root level="warn">
<AppenderRef ref="nelo"/>
<AppenderRef ref="console"/>
</Root>
</Loggers>
</Configuration>
Effective Log Search & Analytics log4j2 SDKの使用例
Nelo2 log4j2 SDKを使用する実際のコード例です。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger("nelo");
...
logger.debug("Effective Log Search & Analytics log4j2 SDK Debug Message");
try {
String npe = null;
npe.toString();
} catch(Exception e) {
logger.error("Effective Log Search & Analytics log4j2 SDK Exception", e);
}
制約事項
- async appenderを使用する場合、転送速度に比べてログの発生速度が速いとqueue sizeを超過して発生したログは転送されません。
- async appenderと基本appenderは以下の基準に沿って選択されることをお勧めします。
- ログの流失を最小化したい場合 : 基本appender
- nelo2 システム障害の際にアプリ性能の低下が懸念される場合: asnyc appender : asnyc appender
トラブルシューティング
1. エラーデータが発生したのにAdminで確認できない場合
ログをEffective Log Search & Analytics 収集サーバに転送後、結果メッセージにエラーがない場合は projectName
が正しいか確認します。
実際エラーデータが転送されたか確認します。設定ファイル(log4j2.xml)でEffective Log Search & Analytics nelo appenderのdebug属性を trueに設定してから実行して、以下のような転送ログが表示されたか確認します。
<!-- define nelo appender -->
<ThriftAppender>
<name>nelo</name>
<collectorUrl>COLLECTOR_HOST</collectorUrl>
<port>COLLECTOR_PORT</port>
<projectName>PROJECT_ID</projectName>
<version>PROJECT_VERSION</version>
<logType>LOG_TYPE</logType>
<logSource>LOG_SOURCE</logSource>
<debug>true</debug>
</ThriftAppender>
[NELO2] Log Append : sent event, return value :
…
FAQ
1. 配置プログラム(または、簡単なテストプログラム)で AsyncAppenderを使用するためには?
batch プログラムの最後に数秒間待機するコードを追加する必要があります。
try {
Thread.sleep(3000L);
} catch (InterruptedException ignore){}
AsyncAppenderは内部にログを記録する別途のデーモンスレッドがあって非同期でログを転送します。
Java batch programではmain threadがすぐ終了するため、log4jAsyncAppenderのデーモンスレッドが生成されてログを送信する前にbatchアプリが終了します。
デーモンスレッドと関係なく生きている一般スレッドがない場合、JVMはすぐ終了します。
従って、上のようにプログラム最後に待機するコードを追加して全てのログを送信してから終了するようにします。
2. Java stack traceをlog4j(NELO2を含む)にロギングするためには?
Action, BO, DAO, Java batch programなどで log4jを利用してstack traceを出力するためには log.error(e.getMessage(), e); の形を使用します。
SLF4J Loggerはメソッドの因子でThrowableのみ受け取るロギングメソッドはサポートしません。
String[] aa = null;
try {
aa[0] = "111";
} catch (NullPointerException e) {
// log.error(e); //SLF4Jではサポートしないメソッド。
log.error(e.getMessage(), e); ///stacktrace 出力
}
3. log4j loggingによる性能低下を最小化するためには?
log4j2.xmlのlogger設定からnameとlevelを使用してfilteringを最大化します。
以下のようにlogger 設定から comまたはorgをDEBUG levelに設定するとloggerで多くのILoggingEvent(log4j)が余計に生成されます。
nelo log4j2 appenderでThresholdがERRORに設定されていて実際にログの転送はされないが、まずはloggerでILoggingEventが生成されてappenderに転送されます。
性能が低下する設定(デベロッパー用でのみ使用)
<Loggers>
<Logger name="nelo" level="debug" additivity="false">
<AppenderRef ref="nelo"/>
<AppenderRef ref="console"/>
</Logger>
<Root level="debug">
<AppenderRef ref="nelo"/>
<AppenderRef ref="console"/>
</Root>
</Loggers>
性能が考慮された設定(運営用でのみ使用)
<Loggers>
<Logger name="nelo" level="error" additivity="false">
<AppenderRef ref="nelo"/>
<AppenderRef ref="console"/>
</Logger>
<Root level="warn">
<AppenderRef ref="nelo"/>
<AppenderRef ref="console"/>
</Root>
</Loggers>
4. thrift bulk転送の際にtimeoutが生じた場合
収集サーバに正常にログを転送できなかった場合、以下のようなログを確認できます。
[NELO2] sendMessage (1426319665440) sendBulk failed.. Error occur : java.net.SocketTimeoutException: Read timed out
この場合、 xml appender設定でtimeoutを増やし、bulkSizeを縮めることによってパケットに入るデータを減らす必要があります。
5.メモリー使用量に関する注意事項
現在提供されるSDKはbulkの転送モードを基本に使用し、bulkSizeは基本値が1000です。
一つのEffective Log Search & AnalyticsログはprojectName など複数のフィールドを含めているため、ログボディーが非常に短い場合でも約1kbのメモリーを占めます。
従って、基本設定の場合、 Nelo2バルクは (ログサイズ+1kb)*1000分のメモリーを占めます。
Javaプロセスを起動する際、最大のヒップを -Xmxオプションに指定できます。この際に上で言及した付加的なメモリー使用量も考慮してください。
特に、bulkSizeオプションをより大きく指定する場合にはより注意してください。