Logback SDK v2 の使用方法

Prev Next

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

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

NELO2 Logback SDK dependencyを追加

以下のように Dependencyを追加します。

圧縮ファイルを展開した後、coreモジュールと logbackモジュールのパスを <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-logback</artifactId>
            <version>1.6.6</version>
            <scope>system</scope>
            <systemPath>/nelo2-java-sdk-logback-1.6.6.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</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は logbackの slf4Jバインドライブラリである logback-classicを含めて提供します。
    slf4jは特性上、同時に1つの bindingのみサポートするため、他の slf4jバインドのためのライブラリを一緒に使用できません。

  • Logbackライブラリのうち SLF4J bindingライブラリは、logback-classicです。
    既存の使用中の参照ライブラリと nelo2 logback SDKで参照するライブラリが重複する場合、問題が発生することがあります。
    この場合、より上位のバージョンを使用することをお勧めします。

Effective Log Search & Analytics logback appenderの設定とオプション

Logbackは logback.groovy -> logback-test.xml -> logback.xmlの順に設定ファイルを検索します。

本書では logback.xmlを基準にして説明します。一般的に使用する logback.xmlの設定は、次の通りです。

<configuration>
    <!-- Console Appender -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level]\(%file:%line\) %msg%n</pattern>
        </encoder>
    </appender>
    <!-- Logger -->
    <logger name="com" additivity="false">
        <level value="debug"/>
        <appender-ref ref="STDOUT" />
    </logger>
    <!-- Root Logger -->
    <root level="warn">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

NELO2 Logback appenderは以下のように設定できます。

<appender name="nelo" class="com.naver.nelo2.logback.ThriftAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>TRACE</level>
    </filter>
    <param name="projectName" value="프로젝트 키"></param>
    <param name="collectorUrl" value="elsa-col.ncloud.com"></param>
    <param name="encoding" value="utf-8"></param>
    <param name="timeout" value="1200"></param>
    <param name="enable" value="true"></param>
    <param name="debug" value="false"></param>
    <param name="version" value="1.0.0"></param>
    <param name="errorCodeType" value="default"></param>
    <param name="port" value="10006"></param>
    <param name="isBulkEnabled" value="true"></param>
</appender>

オプションは次のような項目を設定できます。

  • Appender(転送プロトコルに応じて Appenderのクラス名を選択)

    • Thrift Appender : com.naver.nelo2.logback.ThriftAppender

    • Http Appender : com.naver.nelo2.logback.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: logbackの基本情報のうち、Exception情報を使用。 Exception 정보가 전달되지 않은 경우 (log.error(message)의 형식으로 로그가 기록되는 경우)에는 에러 메시지 전체를 에러코드로 사용함

      例) NullPointerExceptionが発生した場合 => NullPointerException

    • message: エラーメッセージの最初から空白文字までのみ使用。

      例) ダウンロードエラー ダウンロードに失敗しました。=> ダウンロードエラー

    • mdc: SLF4J MDCの「errorCode」項目値を設定して使用する。

      例) MDC.put(“errorCode”, “Login”) => Login

  • debug: Nelo2 appenderのデバッグ用メッセージを出力、デフォルト値 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

Effective Log Search & Analytics logback SDKはログを1件ずつ転送する singleモードと、まとまった単位で転送する bulkモードをサポートします。

xml appender設定で isBulkEnabledを true/falseにして bulk / singleモードを使用できます(デフォルト値 true)。

パフォーマンスに関するリファレンスはプロトコルに沿って以下の表をご参照ください。

10分間単一スレッドで 1kb sizeのログを転送する場合の throughput

  • thrift
    • single mode : 2587.93 logs/sec
    • bulk mode : 6492.99 logs/sec
  • http
    • single mode : 595.86 logs/sec
    • bulk mode : 4617.98 logs/sec

上記のパフォーマンステストに使用した装置のスペックは、次の通りです。

  • ログ転送サーバ: 2GHZ 12core cpu、48G mem
  • ログ収集サーバ: 2.26GHZ 12core cpu、48G mem

備考

  • 負荷に応じて転送パフォーマンスは異なります。
    テストは負荷がない状況で実行され、実際に使用中のインスタンスに送信する際には比較的低いパフォーマンスを示します。
    インスタンス負荷に応じたパフォーマンスの体験は、bulkモードに比べて singleモードでより大きく表示されます。
    そのため、デフォルト値である bulkモードを使用することをお勧めします。

  • 収集サーバが許可する最大パケットのサイズは30MBです。
    クライアントサーバのログパターンを検討し、適切な bulkSizeを設定します(デフォルト値1000)。

AsyncAppender

次のように logbackでサポートする AsyncAppenderを利用し、同じ方式の結果が得られます。

注意すべき設定値には、次のような項目があります。queueSizeのデフォルト値は128ですが、いくつかのアプリケーションでは十分でないことがあります。

そして、includeCallerDataのデフォルト値は falseであり、この場合 AsyncAppenderはログの発生場所情報を無視します。

以下の AsyncAppender設定例をご参照ください。

<appender name="nelo-logback-async" class="ch.qos.logback.classic.AsyncAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>ERROR</level>
    </filter>
    <param name="neverBlock" value="true" />
    <param name="includeCallerData" value="true" />
    <param name="queueSize" value="2048" />
    <appender-ref ref="nelo-logback" />
</appender>

設定値の詳細情報は、次の公式ドキュメントをご参照ください。

AsyncAppenderの使用方法

デフォルトで使用する ThriftAppenderに追加として LogbackAsyncAppenderを使用し、実際のログ転送を別途スレッドで行うように設定できます。

そのためには、以下のように xmlファイルを設定して使用します。

<configuration>
    <!-- Console Appender -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level]\(%file:%line\) %msg%n</pattern>
        </encoder>
    </appender>

    <!-- NELO2 Logback Appender -->
    <appender name="nelo-logback" class="com.naver.nelo2.logback.ThriftAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <param name="projectName" value="프로젝트 키"/>
        <param name="collectorUrl" value="elsa-col.ncloud.com"/>
        <param name="port" value="10006"/>
        <param name="timeout" value="1200" />
        <param name="enable" value="true" />
        <param name="errorCodeType" value="default" />
    </appender>

    <!-- NELO2 Logback Async Appender -->
    <appender name="nelo-logback-async" class="ch.qos.logback.classic.AsyncAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <param name="neverBlock" value="true" />
        <param name="IncludeCallerData" value="true" />
        <param name="queueSize" value="2048" />
        <appender-ref ref="nelo-logback" />
    </appender>

    <!-- Logger -->
    <logger name="com" additivity="false">
        <level value="debug"/>
        <appender-ref ref="STDOUT" />
        <appender-ref ref="nelo-logback-async" />
    </logger>

    <!-- Root Logger -->
    <root level="warn">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="nelo-logback-async" />
    </root>
</configuration>

Effective Log Search & Analytics logback SDKの使用例

Effective Log Search & Analytics Logback SDKを使用する実際のコードの例です。

...
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static Logger logger = LoggerFactory.getLogger(LogbackTest.class);
...
    logger.debug("Effective Log Search & Analytics Logback SDK Debug Message");
    try {
        String npe = null;
        npe.toString();
    } catch(Exception e) {
        logger.error("Effective Log Search & Analytics Logback SDK Exception", e);
    }

制限事項

  • async appenderを使用する場合、転送速度に比べてログ発生速度が速いと queue sizeを超過して発生したログは転送されません。
  • async appenderとデフォルト appenderは以下の基準に沿って選択することをお勧めします。
    • ログ損失を最小化したい場合: デフォルト appender
    • Effective Log Search & Analyticsシステム障害の際にアプリケーションのパフォーマンス低下が懸念される場合: async appender

トラブルシューティング

1. Effective Log Search & Analyticsでログを転送したが、それをウェブで確認できない場合

プロジェクト IDが正しいか確認します。プロジェクト IDが正しくない場合、ウェブのダッシュボードでログは確認できません。

そして実際のエラーデータが転送されたか確認します。設定ファイル(logback.xml)で nelo2 appenderの debugプロパティを trueに設定して実行した後、以下のような転送ログが出力されることを確認します。

<!-- NELO2 Logback Appender -->
<appender name="nelo-logback" class="com.naver.nelo2.logback.ThriftAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>ERROR</level>
    </filter>
    <param name="projectName" value="%YOUR_PROJECT_KEY%"/>
    <param name="collectorUrl" value="elsa-col.ncloud.com"/>
    <param name="port" value="10006"/>
    <param name="timeout" value="1200" />
    <param name="enable" value="true" />
    <param name="errorCodeType" value="default" />
    <param name="debug" value="true" />
</appender>

[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を logbackにロギングするには?

Action / BO / DAO / Java batch programなどで logbackを利用して 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. logback loggingによるパフォーマンス低下を最小化するには?

logback.xmlの logger設定で nameと levelを使用して filteringを最大化できます。

以下のように logger設定で comや orgを DEBUG levelに設定すると、loggerで多くの ILoggingEvent(logback)が余計に作成されます。

nelo logback appenderで Thresholdが ERRORに設定されているため、実際のログ転送は行われませんが、まず loggerで ILoggingEventを作成して appenderに送ります。

パフォーマンスが低下する設定(開発用のみで使用)

<!-- Logger -->
<logger name="com" additivity="false">
    <level value="debug"/>
    <appender-ref ref="STDOUT" />
    <appender-ref ref="nelo-logback" />
</logger>

<!-- Logger -->
<logger name="org" additivity="false">
    <level value="debug"/>
    <appender-ref ref="STDOUT" />
    <appender-ref ref="nelo-logback" />
</logger>

<!-- Root Logger -->
<root level="warn">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="nelo-logback" />
</root>

パフォーマンスを検討した設定(運用向けに使用)

<!-- Logger -->
<logger name="com" additivity="false">
    <level value="error"/>
    <appender-ref ref="STDOUT" />
    <appender-ref ref="nelo-logback" />
</logger>

<!-- Root Logger -->
<root level="warn">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="nelo-logback" />
</root>

4. WASで使用する際に安定的に終了するには?

エラーログが転送中の状況で WAS(Tomcatなど)が終了される場合は、次のような Exceptionが発生して WASが正常に終了されないことがあります。

このような現象を防ぐには、WAS終了時に LoggerContextインスタンスに対して stop()メソッドを呼び出して nelo2 java appenderを closeすると安定的に終了できます。

備考

Springでは Log4Jに対しては org.springframework.web.util.Log4jConfigListenerを提供しますが、Logbackに対しては安定的な終了をサポートする Listenerを提供していません。

Nelo2 logback SDKは独自の LogbackShutdownListenerを提供します。web.xmlに次のような設定を追加すれば、WAS終了時にエラーログが転送されても安定的に終了できます。

<listener>
    <listener-class>
        com.naver.nelo2.logback.LogbackShutdownListener
    </listener-class>
</listener>

5. thrift bulk転送時に timeoutが発生する場合

収集サーバに正常にログを転送できなかった場合、以下のようなログを確認できます。

[NELO2] sendMessage (1426319665440) sendBulk failed..  Error occur : java.net.SocketTimeoutException: Read timed out

この場合、xml appender設定で timeoutを増やし bulkSizeを縮めることで1つのパケットに入るデータを減らします。

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

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

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

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

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

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

7. httpClientのロギング関連警告メッセージ

httpプロトコルを使用する場合、アプリケーションの起動時に以下のようなログが発生します。

これは httpClientライブラリが apache loggingフレームワークを使用するためであり、ここで作成したログは root loggerに残ります。

SLF4J: The following loggers will not work because they were created
SLF4J: during the default configuration phase of the underlying logging system.
SLF4J: See also http://www.slf4j.org/codes.html#substituteLogger
SLF4J: org.apache.http.impl.conn.PoolingClientConnectionManager
SLF4J: org.apache.http.impl.conn.DefaultClientConnectionOperator
SLF4J: org.apache.http.impl.client.DefaultHttpClient