ようへいの日々精進XP

よかろうもん

fluentd + Elasticsearch + kibana + siege でお手軽に web サイトのレスポンスタイムを可視化する試み(2)

はじめに

前回の記事fluentd から Elasticsearch にデータを放り込む際にフィールドタイプが軒並み文字列として扱われてしまった対応として fluent-plugin-typecast を使ってフィールドタイプを変更して Elasticsearch にデータを放り込んで対応したが、別のアプローチとして @johtani さんに以下のようなコメントを頂いたので早速試してみる!

elasticsearch側でマッピングを定義してあげてからデータを登録するとおそらく、floatなどは文字列が来ても登録できると思います。 見た感じ、フィールド名などは決まっているようですし。

コメント頂けるだけでも嬉しいのにわざわざ手順まで記載頂いて感謝!有難うございます!


参考


やってみる

何はともあれやってみる。引き続き、こちら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 にデータを登録してみる。

f:id:inokara:20131119062235p:plain

Elasticsearch-head で確認すると上記のように登録されている。また、コマンドラインから検索するとこちらのようにデータ登録を確認出来た。

kibana で確認

トントン拍子に Elasticsearch まで登録出来たので kibana でもサクッとレスポンスタイムが見れちゃうのかと思ったら甘かった。

f:id:inokara:20131119062607p:plain

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

f:id:inokara:20131119064344p:plain

デフォルトでは @timestampTime Field として利用するみたい...とは言え、独自のフィールドを Time Fileld の指定は出来るので試行錯誤してみたが断念。


試行錯誤した結果

fluent-elasticsearch-plugin の設定から見直しつつ参考にさせて頂いた記事を整理すると...

  • logstash_format true を無効にすると @timestamp が付かないので Elasticsearch 側で @timestamp の代わりになるような日付型のフィールドを用意してあげる(用意してみたがうまく kibana でグラフ化出来ず...)
  • logstash_format true を有効にすると lostash-YYYY.MM.DD という名前のインデックスを作ってくれるがデータタイプは軒並み文字列となる

また、

  • Elasticsearchtemplate 機能を使えば lostash-YYYY.MM.DD という名前のインデックスのデータタイプを指定することが出来る

更に、

と教えて頂いたので、気を取り直して Elasticsearchtemplate 機能 を使ってあらかじめ 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 で確認すると以下のように表示された。

f:id:inokara:20131120073443p:plain

ヒストグラムでレスポンスタイムが表示された

kibana でも確認してみる。

f:id:inokara:20131120064226p:plain

ちゃんとレスポンスタイムの推移が確認出来るようになった。


最後に

  • データの型が決まっているようであればあらかじめマッピングを決め打ちしておいた方が良さそう
  • kibana で日付、時刻の取り扱いについては Time Fileld の指定が重要になる
  • Time Fileld はデフォルトで @timestamp が利用されるが独自のフィールドを利用することは可能(だけど自分はうまく反映されていない...)

ということで、Time Fileld について宿題が残ってしまったが、 @johtani さんに頂いたコメントをきっかけに Elasticsearch について理解を深めることが出来た。 @johtani さん有難う御座いました!