Log4j2 SDK v2 の使用方法

Prev Next

Classic/VPC環境で利用できます。

ここでは Effective Log Search & Analytics log4j2 SDKの使用方法を説明します。NELOは Effective Log Search & Analyticsのプロジェクトコード名です。

NELO2 log4j2 SDK dependencyを追加

以下のように Dependencyを追加します。
圧縮ファイルを展開した後、coreモジュールと log4j2モジュールのパスを <systemPath> に追加します。

<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は特性上、同時に1つの 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_KEY</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_KEY</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: プロジェクトキー。Effective Log Search & Analyticsのプロジェクト情報で作成したプロジェクトのキーを確認できます。

  • 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

    • message: エラーメッセージの最初から空白文字までのみ使用。
      例) ダウンロードエラー ダウンロードに失敗しました。=> ダウンロードエラー

    • mdc: SLF4J MDCの「errorCode」項目値を設定して使用する。
      例) MDC.put(“errorCode”, “Login”) => Login

  • debug: Effective Log Search & Analyticsのデバッグ情報を表示。デフォルト値は false。

    • このオプション値は全域的に適用され、「true」が「false」より優先されます。つまり、複数のアペンダーが宣言されており、そのうち1つの 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 keyをリネームするルールです。

    • format: key1:newKey1;key2:newkey2;...
      例) mdcConversionRuleを time:date;fullname:nameに設定し、この keyが存在する時に MDC keyの _time_を dateに、fullnameを nameにリネームするということです。

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モードに比べて singleモードでより大きく表示されます。
    そのため、デフォルト値である 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_KEY</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_KEY</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システム障害の際にアプリケーションのパフォーマンス低下が懸念される場合: async 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_KEY</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を縮めることで1つのパケットに入るデータを減らします。

5. メモリ使用量に関する注意事項

現在提供される SDKは bulk転送モードをデフォルトで使用し、bulkSizeはデフォルト値が1000です。

1つの Effective Log Search & Analyticsログは projectNameなどの複数のフィールドを含めているため、ログボディが非常に短い場合にも1kb程度のメモリを使用します。

そのため、デフォルト設定の場合に Nelo2バルクは(ログサイズ+1kb)*1000程度のメモリを使用します。

Javaプロセスを起動する場合、最大ヒープを-Xmxオプションに指定できます。この時、上で言及した付加的なメモリ使用量も検討してください。

特に bulkSizeオプションをより大きく指定する場合は、特にご注意ください。