Edited at

Elasticsearchでintegerになっていて欲しいところがstringになっていた時の対処法

More than 3 years have passed since last update.


問題

Elasticsearch, Fluentd, Kibanaの構成を作り、apacheやapplicationのログを送るシステムまでは完成させたのだけれど、kibana上でdashboardを作っていた時に、apacheのresponse timeや、データサイズのfieldが上手くソートできない問題に遭遇。

stringで見てるっぽいなーってとこまではわかっている状態。


調査

とりあえず、mappingのrequestを投げるためにindexの名前とかを知りたい。

$ curl -XGET http://localhost:9200/_cat/indices?v

health status index pri rep docs.count docs.deleted store.size pri.store.size
yellow open tarr-1970.01.01 5 1 109 0 132.9kb 132.9kb
yellow open tarr-2015.08.05 5 1 31976 0 4.4mb 4.4mb
yellow open ssltest-2015.07.31 5 1 5 0 22.1kb 22.1kb
yellow open tarr-2015.08.19 5 1 30228 0 3.8mb 3.8mb
yellow open tarr-2015.08.14 5 1 30225 0 3.8mb 3.8mb
yellow open tarr-2015.08.06 5 1 30849 0 4.1mb 4.1mb
yellow open tarr-2015.08.18 5 1 35344 0 5.5mb 5.5mb
yellow open tarr-2015.08.10 5 1 30223 0 3.9mb 3.9mb

...

こんな感じになってた。tarr-2015.08.23あたりを見てみるかと考える。

下記のコマンドを叩けば、indexのmappingは見ることができるのだけれど、

$ curl -X GET localhost:9200/rdrive-2015.08.23/_mapping?pretty=true

documentが複数出てきて見づらいので、documentまで指定する。

$ curl -X GET localhost:9200/tarr-2015.08.23/ssl_access_log/_mapping?pretty=true

{
"tarr-2015.08.23" : {
"mappings" : {
"ssl_access_log" : {
"properties" : {
"@timestamp" : {
"type" : "date",
"format" : "dateOptionalTime"
},
"agent" : {
"type" : "string"
},
"code" : {
"type" : "string"
},
"cookie" : {
"type" : "string"
},
"forwardedfor" : {
"type" : "string"
},
"host" : {
"type" : "string"
},
"method" : {
"type" : "string"
},
"path" : {
"type" : "string"
},
"referer" : {
"type" : "string"
},
"response_time" : {
"type" : "string"
},
"size" : {
"type" : "string"
},
"tag" : {
"type" : "string"
},
"user" : {
"type" : "string"
}
}
}
}
}
}

やっぱりresponse_timesizeがstringになっているなー。

あとから気づいたんだけど、下記で以前同じようなことをやっていて、その時はtemplateを変えていた。しかし、これってindexが新しくなったタイミング(今回は毎日一回)でまたstringに戻ってしまう。なので、このやり方は正しくなくて、fluentdの設定を変更するべき。

fluentd -> elasticsearchでつっこんだデータのstringになっているやつをintegerに変換する - Qiita


fluentdの設定

fluentdの設定はこういう感じにしていた。

<source>

type tail
format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*) "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" (?<cookie>[^ ]*) (?<response_time>[^ ]*) (?<forwardedfor>[^ ]*)$/
time_format %d/%b/%Y:%H:%M:%S %z
pos_file /path/to/pos/tarr.pos
path /path/to/logs/ssl_access_log
tag ssl_access_log.tarr.hostname
</source>

tail Input Plugin | Fluentd

上記を参考に、この設定を追加する。

types size:integer,response_time:integer

<source>

type tail
format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*) "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" (?<cookie>[^ ]*) (?<response_time>[^ ]*) (?<forwardedfor>[^ ]*)$/
time_format %d/%b/%Y:%H:%M:%S %z
pos_file /path/to/pos/tarr.pos
types size:integer,response_time:integer
path /path/to/logs/ssl_access_log
tag ssl_access_log.tarr.hostname
</source>

この時注意すべきなのは、

types size:integer, response_time:integer

このように、,の後にスペースを入れていると、sizeのみが反映されて、response_timeは反映されなかったことだ。


indexの削除

curl -XDELETE 'http://localhost:9200/tarr-2015.08.24'

これで削除したら、新しいindexからstringからnumberに変わっていた。