FluentdからElastic Searchへ投入するデータの型を変換する
元々やりたかった事
- apacheのアクセスログをfluentdで取り込んでElastic Searchに投入してKibanaで分析したい
- アクセスログはちょっと形式をいじってレスポンスタイムが記録されるようになっている
- ElasticSearchで10秒以上とか遅いアクセスを抽出したい
困った事
- 標準のapacheのログ形式は使えないので自前で下記の感じで正規表現を定義
fluent.conf
<source>
type tail
format /^(?<host>[^ ]*) - - \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (
?<code>[^ ]*) (?<size>[^ ]*) (?<restime>[^ ]*) (?<resstate>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<
agent>[^\"]*)")?.*$/
path /path/to/access.log
time_format %d/%b/%Y:%H:%M:%S %z
tag apache.access
</source>
- restimeというキーでレスポンスタイムがでるのだけど、文字列型でElastic Searchに登録されてしまい、大小比較が辞書式になってしまっている
- どうも標準の形式を使うと自動的に型変換されるけど、正規表現でカスタムの定義をすると全部文字列型になってしまうらしい
対応案1:Elastic Search側で変換する(失敗)
- Elastic Search側でマッピングを指定することができるらしい
対応案2:fluentd側で変換する(成功)
- fluentdのプラグインでfluent-plugin-typecastというのを発見
- 下記の感じで適用
- item_typesという項目でマッピングを記述する
# gem install fluent-plugin-typecast
fluent.conf
<match apache.access>
type typecast
item_types restime:integer
prefix typed
</match>
<match typed.apache.access>
type elasticsearch
(snip)
</match>
結果
- 無事変換できました。
- こんな↓感じでKibanaからクエリ投げると10秒以上のレスポンスのアクセスを抽出できました。
restime:[10 TO *]
おわりに
ElasticSearch側のmappingで解決できなかった謎は解けなかったけどよしとします