Docker コンテナーでいくつかの Spring Boot アプリケーションを実行しています。ファイルにログを記録したくないので、代わりにコンソールにログを記録し、logspout を使用してログをLogstashに転送しています。logstash-logback-encoderを使用して、アプリケーションからのすべてのログを JSON 形式で記録しています。
これらとは別に、Spring Boot アプリケーションを開始する前に docker コンテナーによって作成されるいくつかのログ (コンソール出力) もあります。これらは JSON 形式ではありません。
これらの両方に、Logspout は Logstash に送信する前にメタデータ (コンテナー名、コンテナー ID など) を追加します。以下は、両方の形式のログの例です。
- コンテナーから直接 (JSON なし)
<14>1 2016-12-01T12:58:20Z 903c18d47759 com-test-myapp 31635 - - テストするアクティブなプロファイルを設定しています
- アプリケーション ログ (JSON 形式)
<14>1 2016-12-01T13:08:13Z 903c18d47759 com-test-myapp 31635 - - {"@timestamp":"2016-12-01T13:08:13.651+00:00","@version":1 ,"message":"ここにログ メッセージが入ります","logger_name":"com.test.myapp.MyClass","thread_name":"http-nio-8080-exec-1","level":"DEBUG" ,"レベル値":10000,"ホスト名":"903c18d47759"}
以下は、Logstash の grok 構成です。
input {
tcp {
port => 5000
type => "logspout-syslog-tcp"
}
}
filter {
if [type] == "logspout-syslog-tcp" {
grok {
match => {
"message" => [
"<%{NUMBER:syslogPriority}>1 %{TIMESTAMP_ISO8601:eventTimestamp} %{BASE16NUM:containerId} %{DATA:containerName} %{NUMBER:containerPort} - - %{DATA:jsonLog}",
"<%{NUMBER:syslogPriority}>1 %{TIMESTAMP_ISO8601:eventTimestamp} %{BASE16NUM:containerId} %{DATA:containerName} %{NUMBER:containerPort} - - %{DATA:regularLog}"
]
}
}
json {
source => "jsonLog"
target => "parsedJson"
remove_field=>["jsonLog"]
}
mutate {
add_field => {
"level" => "%{[parsedJson][level]}"
"thread" => "%{[parsedJson][thread_name]}"
"logger" => "%{[parsedJson][logger_name]}"
"message" => ["%{[parsedJson][message]}"]
}
}
}
}
output {
elasticsearch { hosts => ["localhost:9200"] }
stdout { codec => rubydebug }
}
これに基づいて、JSON の各フィールドを Elasticsearch/Kibana のフィルターとして使用できるようにしたいと考えていました。しかし、それらのフィールドの値を取得できません。以下のように Kibana に表示されます。
ここで何が欠けているのかわかりません。JSON からフィールドを抽出するにはどうすればよいですか? また、Grok フィルターは、JSON ログと非 JSON ログの両方を処理するのに適切ですか?
ありがとう、アヌープ