まめログ

Javaプログラマの歩み

Logstashで一部がkey value形式のログをパースする #elasticsearch

Logstashで取り込むログは多種多様で、色々なテンプレートも用意されています。

ただ、アプリケーションログはそれぞれのアプリで独自のフォーマットで記述されていることが多いと思います。

f:id:mamepika:20170226223831p:plain

今回、ちょっと複雑なログの形式として
項目が":"区切りで且つKey=Value形式の項目があるログをパース出来たので、方法を残しておきます。


ログはこんな形式です。

2017-02-26_11-46-00.123:hostap1:bwegaa3JkLKJIHGKGGIkjahawlwk2134:10000123:OUT:OAUT45    :OperateId=1Update&0&ProcessId=2kdajgkagkdjgjgkgjgkb&ProcessPass=214resdkljg6ykdhjglkgshg&SalesDate=20170226&TenantId=0001&TransactionDate=20170226&ResponseCd=OK
2017-02-26_12-46-00.123:hostap1:bwegaa3JkLKJIHGKGGIkjahawlwk2134:10000123:OUT:OAUT45    :OperateId=1Update&0&ProcessId=2kdajgkagkdjgjgkgjgkb&ProcessPass=214resdkljg6ykdhjglkgshg&SalesDate=20170226&TenantId=0001&TransactionDate=20170226&ResponseCd=NG
2017-02-26_12-45-00.123:hostap1:bwegaakJkLKJIHGKGGIkjahawlwk2134:10000123:IN :OAUT45    :OperateId=1Create&0&ProcessId=d5aaa2jgkjgghhhglalkg&ProcessPass=234resdkljg6ykdhjglkgshg&SalesDate=20170226&TenantId=0001&TransactionDate=20170226
2017-02-26_12-46-00.123:hostap1:bwegaa3JkLKJIHGKGGIkjahawlwk2134:10000123:OUT:OAUT45    :OperateId=1Update&0&ProcessId=2kdajgkagkdjgjgkgjgkb&ProcessPass=214resdkljg6ykdhjglkgshg&SalesDate=20170226&TenantId=0001&TransactionDate=20170226&ResponseCd=NG

処理日付、サーバ名、セッションIDが":"区切りで、最後の項目にPOSTされた内容がKey=Value形式で記述されています。

Logstashの設定ファイルは以下のような感じで記述しました。

input{
    file{
      path => "C:\dev\inout.txt"
      start_position => "beginning"
    }
}
filter{
     csv{
       columns => ["processingDate","hostName","sessionId","merchantId","inout","functionId","telegram"]
       separator => ":"
     }
     date{
      match => ["processingDate" , "yyyy-MM-dd_HH-mm-ss.SSS"]
     }
     kv{
       source => "telegram"
       field_split => "&?"
     }
     mutate{
       remove_field => ["telegram","@version","host"]
     }
}
output{
    elasticsearch{
       hosts => ["<Elasticsearchが動作しているサーバのIPアドレス>"]
       index => "inout-%{+YYYYMMdd}"
    }
}       

filter-kv

ここが今回のキモです。
csvフィルターで":"に項目分けをされた項目を
sourceで指定し、field_splitで"&?”を指定することでKey=Valueをそれぞれの項目として抽出できます。
(dateフィルターで、同じようなことをしているので、もしかしたら出来るかなとやってみたら見事出来ました。)

Elasticsearchに投入しKibanaで見てみます。

f:id:mamepika:20170226224617p:plain


項目数に差異があっても同じインデックスに格納されていますね。
便利!
f:id:mamepika:20170226225045p:plain

f:id:mamepika:20170226225058p:plain

検索もきちんと出来ます。

f:id:mamepika:20170226225408p:plain