はじめに
前回の記事で fluentd から Elasticsearch にデータを放り込む際にフィールドタイプが軒並み文字列として扱われてしまった対応として fluent-plugin-typecast を使ってフィールドタイプを変更して Elasticsearch にデータを放り込んで対応したが、別のアプローチとして @johtani さんに以下のようなコメントを頂いたので早速試してみる!
elasticsearch側でマッピングを定義してあげてからデータを登録するとおそらく、floatなどは文字列が来ても登録できると思います。 見た感じ、フィールド名などは決まっているようですし。
コメント頂けるだけでも嬉しいのにわざわざ手順まで記載頂いて感謝!有難うございます!
参考
- johtani / double_mapping_test.json
- mapping
- core types
- deverton / logstash-template.json
- fluentd-plugin-elasticsearchでのログ時刻の扱い
- Elasticsearchにmappingをtemplate設定してみた
- Kibana + ElasticSearch + fluentd でDBスロークエリログなどを集計し表示したい
やってみる
何はともあれやってみる。引き続き、こちらの Docker コンテナを利用して作業を進める。 サクッと作って、サクッと捨てられるのがイイ。
インデックス作成
まずは index を登録。
curl -XPUT 'http://localhost:9200/siege/'
マッピングの登録
siege が出力するログは以下のようなログ。
Date & Time, Trans, Elap Time, Data Trans, Resp Time, Trans Rate, Throughput, Concurrent, OKAY, Failed 2013-11-19 00:51:34, 9, 5.83, 0, 1.86, 1.54, 0.00, 2.87, 9, 0 2013-11-19 00:54:03, 9, 5.97, 0, 1.99, 1.51, 0.00, 2.99, 9, 0 2013-11-19 01:00:00, 9, 6.59, 0, 2.11, 1.37, 0.00, 2.88, 9, 0
ログの出力に合わせてマッピングタイプを登録してみる。
curl -XPUT localhost:9200/siege/webresp_time/_mapping -d '{ "webresp_time" : { "numeric_detection" : false, "properties" : { "date" : {"format" : "YYYY-MM-dd HH:mm:ss","type" : "date"}, "Trans" : {"type" : "integer"}, "Elap_Time" : {"type" : "double"}, "Data_Trans" : {"type" : "double"}, "Resp_Time" : {"type" : "double"}, "Trans_Rate" : {"type" : "double"}, "Throughput" : {"type" : "double"}, "Concurrent" : {"type" : "double"}, "OKAY" : {"type" : "integer"}, "Failed" : {"type" : "integer"} } } }'
td-agent.conf
そして、ログを Elasticsearch に放り込む為に td-agent.conf を以下のように修正する。
<source>
type tail
path /tmp/test_log
pos_file /tmp/test.pos
tag siege.access
format /^(?<date>(\d{4})-(\d{2})-(\d{2}) (\d{2}:)(\d{2}):(\d{2})),\s{1,}(?<Trans>\d+(\.\d+)?),\s{1,}(?<Elap_Time>\d+(\.\d+)?),\s{1,}(?<Data_Trans>\d+(\.\d+)?),\s{1,}(?<Resp_Time>\d+(\.\d+)?),\s{1,}(?<Trans_Rate>\d+(\.\d+)?),\s{1,}(?<Throughput>\d+(\.\d+)?),\s{1,}(?<Concurrent>\d+(\.\d+)?),\s{1,}(?<OKAY>\d+),\s{1,}(?<Failed>\d+)$/
</source>
<match siege.access>
type elasticsearch
include_tag_key true
tag_key @log_name
host 127.0.0.1
port 9200
index_name siege
type_name webresp_time
logstash_prefix siege
flush_interval 10s
</match>
fluent-plugin-typecast の利用を止めてみた。
データ登録を確認
siege を実行して td-agent 経由で Elasticsearch にデータを登録してみる。

Elasticsearch-head で確認すると上記のように登録されている。また、コマンドラインから検索するとこちらのようにデータ登録を確認出来た。
kibana で確認
トントン拍子に Elasticsearch まで登録出来たので kibana でもサクッとレスポンスタイムが見れちゃうのかと思ったら甘かった。

上記のように index を独自の index 名を登録してみたが、以下のようなエラーが出てしまい、前回の記事のように Histgram からレスポンスタイムの自動計算等が出来ない状態なって悩む。

デフォルトでは @timestamp を Time Field として利用するみたい...とは言え、独自のフィールドを Time Fileld の指定は出来るので試行錯誤してみたが断念。
試行錯誤した結果
fluent-elasticsearch-plugin の設定から見直しつつ参考にさせて頂いた記事を整理すると...
logstash_format trueを無効にすると@timestampが付かないのでElasticsearch側で@timestampの代わりになるような日付型のフィールドを用意してあげる(用意してみたがうまくkibanaでグラフ化出来ず...)logstash_format trueを有効にするとlostash-YYYY.MM.DDという名前のインデックスを作ってくれるがデータタイプは軒並み文字列となる
また、
Elasticsearchのtemplate機能を使えばlostash-YYYY.MM.DDという名前のインデックスのデータタイプを指定することが出来る
更に、
@inokara こちらこそよろしくですー。(おそらくうまくいくはずですw)あとは、インデックスを日単位とかで切り替えるようでしたら、このへんも使えるかと。 http://t.co/vRrXMig02f
— Jun Ohtani (@johtani) 2013, 11月 18
と教えて頂いたので、気を取り直して Elasticsearch の template 機能 を使ってあらかじめ lostash-YYYY.MM.DD のインデックスのデータタイプを指定することにした。
template 機能を使ってインデックスのデータタイプを指定
以下のようにデータタイプを指定したテンプレートを登録。
curl -XPUT localhost:9200/_template/my_template -d ' { "template" : "logstash-*", "mappings" : { "fluentd": { "properties": { "date" : {"format" : "YYYY-MM-dd HH:mm:ss","type" : "date"}, "Trans" : {"type" : "integer"}, "Elap_Time" : {"type" : "double"}, "Data_Trans" : {"type" : "double"}, "Resp_Time" : {"type" : "double"}, "Trans_Rate" : {"type" : "double"}, "Throughput" : {"type" : "double"}, "Concurrent" : {"type" : "double"}, "OKAY" : {"type" : "integer"}, "Failed" : {"type" : "integer"} } } } } '
上記のように登録して td-agent を再起動してデータが登録されるのを待つ。この場合には明示的に @timestamp を指定しなくても fluentd 側で宜しくやってくれる。
elasticseach-head で確認すると以下のように表示された。

ヒストグラムでレスポンスタイムが表示された
kibana でも確認してみる。

ちゃんとレスポンスタイムの推移が確認出来るようになった。
最後に
- データの型が決まっているようであればあらかじめマッピングを決め打ちしておいた方が良さそう
kibanaで日付、時刻の取り扱いについてはTime Fileldの指定が重要になるTime Fileldはデフォルトで@timestampが利用されるが独自のフィールドを利用することは可能(だけど自分はうまく反映されていない...)
ということで、Time Fileld について宿題が残ってしまったが、 @johtani さんに頂いたコメントをきっかけに Elasticsearch について理解を深めることが出来た。 @johtani さん有難う御座いました!