読者です 読者をやめる 読者になる 読者になる

Logbackでlogstash形式のログを出力し、fluentdでElasticsearchに転送する

今ちょっとしたmicroservicesをKotlin + Spring Bootで書いているんですが、ログをJSONで出力してfluentdからElasticsearchに送信するにはどうするのがスマートなのかと思いを馳せていました。

Java系のロガーといえばlogbackがかなり有名で広く利用されていますが、JSONを出力するとなると独自に作りこみをしたりlogback-jacksonあたりを利用したりというのを思いつくところです。また、Elasticsearchに投げてkibanaで参照するとなるとlogstash形式が望ましいところ。

というわけでlogstashのGitHub organizationを漁っていたところまさに求めていたものがあったというだけのお話。ただの備忘です。

logstash-logback-encoder

github.com

logstash-logback-encoderを利用すれば、logbackでのロギングを簡単にJSONかつlogstash形式で出力することができます。

導入方法はかなりシンプル。まずはlogstash-logback-encoderへの依存を追加する。Gradleであればbuild.gradleに以下のように設定。

build.gradle
dependencies {
    compile "net.logstash.logback:logstash-logback-encoder:4.7"
}
logback.xml

logbackの設定といえば、最近はGroovyでもできますがここではxml形式で。

コンソールはシンプルにプレーンテキストでのロギングにして、ファイル出力はRollingFileAppenderを使ったログローテートを設定していますが、ここにencoderとしてnet.logstash.logback.encoder.LogstashEncoderを設定します。こうするだけでfluentdに食わせられるログが出せる。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/app.%d{yyyy-MM-dd}.log.tar.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>
                [%-5level][%d{yyyy-MM-dd HH:mm:ss.SSS}] %msg%n
            </Pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>

</configuration>
出てるログ

例えば、SpringBootであれば以下のようなアプリログがlogstash形式でずらずらと出力されるはずです。

{"@timestamp":"2016-09-12T20:57:07.291+09:00","@version":1,"message":"Root WebApplicationContext: initialization completed in 2670 ms","logger_name":"org.springframework.web.context.ContextLoader","thread_name":"localhost-startStop-1","level":"INFO","level_value":20000,"HOSTNAME":"yourhostname"}

あとはよしなにfluentdの設定をすればいい。

( ´_ゝ`)フーン