Spring Boot + KotlinでLogstashを使ってログ出力

Logstatshのお試しとして、Spring Boot + kotlinのアプリに導入したときのメモ。

ビルドツールはgradleを使う

buildscript {
    ext {
        springBootVersion = '1.4.1.RELEASE'
        kotlin_version = '1.0.4'
        logstash_logback_encoder_version = "4.7"
    }
...
}
dependencies {
    compile "org.springframework.boot:spring-boot-starter"
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "org.springframework.boot:spring-boot-starter-web"

    compile "net.logstash.logback:logstash-logback-encoder:$logstash_logback_encoder_version"
}

logback.xmlにappender追加

    <appender name="EVENT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/event.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/event.%d{yyyy-MM-dd}.log.tar.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

encoder classにLogstashEncoderを記述する。

簡易的なコントローラーで出力してみる

@RestController
open class EventController {

    val log: Logger = LoggerFactory.getLogger("EVENT");

    data class EventLog(val name: String, val type: String)

    @RequestMapping(value = "/event", method = arrayOf(RequestMethod.GET))
    fun index(): String {
        log.info(getLog("event", "click"))
        return "ok"
    }

    fun getLog(name: String, type: String): String {
        return Moshi.Builder().build()
                .adapter(EventLog::class.java)
                .toJson(EventLog(name, type))
    }
}
出力例
{"@timestamp":"2016-11-07T10:29:29.333+09:00","@version":1,"message":"{\"name\":\"event\",\"type\":\"click\"}","logger_name":"EVENT","thread_name":"http-nio-8080-exec-1","level":"INFO","level_value":20000,"HOSTNAME":"xxxx"}

JSONパーサーにmoshiを使う

イベントのオブジェクトをjsonにしてみたかったのでmoshiを利用してみた。

github.com

toJsonする
    fun getLog(name: String, type: String): String {
        return Moshi.Builder().build()
                .adapter(EventLog::class.java)
                .toJson(EventLog(name, type))
    }