はじめに
Fluentd の in_tail プラグインでログファイルを読み込む際に、
特別な形式ではないフォーマットだと正規表現を駆使して頑張る必要がありますが
JSON形式でログを出力してしまえばそんな手間も無くなります。
(grepビリティは低いですが・・・)
依存ライブラリの定義
バージョンは現時点で最新のものを埋め込んでいます。
Mavenを使っている場合
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-core</artifactId>
<version>0.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId>
<version>0.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-jackson</artifactId>
<version>0.1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.2</version>
</dependency>
</dependencies>
SBTを使っている場合
libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % "1.7.12",
"ch.qos.logback" % "logback-core" % "1.1.3",
"ch.qos.logback" % "logback-classic" % "1.1.3",
"ch.qos.logback.contrib" % "logback-json-core" % "0.1.2",
"ch.qos.logback.contrib" % "logback-json-classic" % "0.1.2",
"ch.qos.logback.contrib" % "logback-jackson" % "0.1.2",
"com.fasterxml.jackson.core" % "jackson-core" % "2.5.2",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.5.2",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.5.2"
)
補足1
Jackson2 を使うには logback-jackson 0.1.2 を使う必要があります。
logback-jackson 0.1.1 は Jackson1 に依存しています。
Jackson1 と Jackson2 はネームスペースが異なります。
補足2
logback-json-classic 0.1.2 は org.slf4j.Marker
に対応していないため
出力するJSONには含まれません。
MDCなどは普通に使えます。
補足3
jackson-annotations は不要かもしれません(未確認)
logback.xml の定義
<property name="MONITORING_LOG" value="${LOG_DIR}/monitoring.log" />
<appender name="FILE_MONITORING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${MONITORING_LOG}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${MONITORING_LOG}.%d.gz</fileNamePattern>
<maxHistory>14</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<!-- <prettyPrint>true</prettyPrint> -->
</jsonFormatter>
<timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</timestampFormat>
<includeContextName>false</includeContextName>
<appendLineSeparator>true</appendLineSeparator>
</layout>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE_MONITORING" />
</root>
補足4
タイムスタンプのフォーマットで使っている XXX は JDK7 から使用可能です。
補足5
細かいオプションについては下記を見ると大体分かるはずです。
https://github.com/qos-ch/logback-contrib/blob/2161638c59572c33e76220306ac4b6fbbf863776/json/core/src/main/java/ch/qos/logback/contrib/json/JsonLayoutBase.java
https://github.com/qos-ch/logback-contrib/blob/2161638c59572c33e76220306ac4b6fbbf863776/json/classic/src/main/java/ch/qos/logback/contrib/json/classic/JsonLayout.java
https://github.com/qos-ch/logback-contrib/blob/2161638c59572c33e76220306ac4b6fbbf863776/jackson/src/main/java/ch/qos/logback/contrib/jackson/JacksonJsonFormatter.java
ログ
出力結果は下記のようになります。
文字列内の改行文字などは \n で出力されるため、1つのログエントリにつき1行になります。
{"timestamp":"2015-04-05T14:45:28.481+09:00","level":"WARN","thread":"pool-1-thread-1-ScalaTest-running-SQSHelperSpec","logger":"helpers.aws.sqs.SQSHelperSpec","message":"com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain"}
{"timestamp":"2015-04-05T14:45:31.526+09:00","level":"WARN","thread":"pool-1-thread-1-ScalaTest-running-SQSHelperSpec","logger":"helpers.aws.sqs.SQSHelperSpec","message":"com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain"}
{"timestamp":"2015-04-05T14:45:31.775+09:00","level":"WARN","thread":"pool-1-thread-1-ScalaTest-running-SQSHelperSpec","logger":"helpers.aws.sqs.SQSHelperSpec","message":"com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain"}
{"timestamp":"2015-04-05T14:45:31.864+09:00","level":"WARN","thread":"pool-1-thread-1-ScalaTest-running-SQSHelperSpec","logger":"helpers.aws.sqs.SQSHelperSpec","message":"com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain"}