ども、 cloudpack の かっぱ (@inokara) です。
はじめに
蓋を開けると…
fluentd を全然使いこなせていないでちょっとずつ復習を兼ねて使ったことないプラグインを使ってみる。今回は fluent-plugin-datacounter を使ってみる。
ゴール
今回は fluent-plugin-datacounter を利用して各ホストから送信されるレコードに含まれるキーの値を集計して Datadog で可視化するまで。
図で表すと上のような流れにしたい。
fluent-plugin-datacounter とその他、今回登場するプラグイン
参考
fluent-plugin-datacounter
- tagomoris/fluent-plugin-datacounter · GitHub
- レコードから正規表現パターンでマッチした数を集計するプラグイン
fluent-plugin-forest
- tagomoris/fluent-plugin-forest · GitHub
- タグ、プレースホルダを利用して、各種プラグインの設定に対して動的な値を設定するプラグイン
fluent-plugin-map
- tomity/fluent-plugin-map · GitHub
- 特定のフィールド内容を Ruby を利用して加工するプラグイン
- レコードに対して Ruby の map メソッドを使ってレコード内のキーを指定し値を取り出して加工するプラグイン(だと思う)
fluent-plugin-ddは
- winebarrel/fluent-plugin-dd · GitHub
- Datadog にメトリクスデータを書き込むプラグイン
- fluent-plugin-datadog というのもあるらしい
それぞれの設定
構成
尚、設定は Host3 に行うことになる。
fluent-plugin-datacounter と fluent-plugin-map の設定
datacounter プラグインには以下のようなレコードが入ってくることを想定。
{"status":"403","reqtime":"0.123","method":"GET","uri":"http://dev.hogehoge.test/v1/foo/bar?id=1"}"
以下のような設定を行った。
type copy type datacounter count_interval 1m aggregate all count_key status pattern1 2xx ^2dd$ pattern2 3xx ^3dd$ pattern3 4xx ^4dd$ pattern4 5xx ^5dd$ # tag datacount.accesslog type forest subtype copy type file path /tmp/fluent-${tag_parts[1]}.log type copy type map map ["stat." + tag, time, {"metric" => "stat.404.count","value" => record["404_count"].to_i}] type map map ["stat." + tag, time, {"metric" => "stat.2xx.count","value" => record["2xx_count"].to_i}] type map map ["stat." + tag, time, {"metric" => "stat.3xx.count","value" => record["3xx_count"].to_i}] type map map ["stat." + tag, time, {"metric" => "stat.4xx.count","value" => record["4xx_count"].to_i}] type map map ["stat." + tag, time, {"metric" => "stat.5xx.count","value" => record["5xx_count"].to_i}] type stdout
ポイントとしては…
count_key status
でカウントするキーstatus
を指定patternx xxx ^xdd$
でカウントする値を正規表現で指定aggregate all
でtype datacounter
を通過する全てのタグのレコードを対象とすることを指定type map
では Ruby でハッシュを扱う際にキーを指定して値を取得する感じで各キーの値を取得、さらにtype dd
で Datadog にレコードを送る際に{"metric":"xxx.xxx.xxx", "value": NN}
というフォーマットで送信する必要があるのでそのように配列を生成しているtype forest
でdatacounter
で処理される前の状態のレコードをホスト毎にファイルに書き出す設定を行っている(type forest
とtype datacounter
を一緒に使う場合に注意したい…)
fluent-plugin-dd の設定
以下のようなレコードが入ってくることを想定。
2015-03-08 15:36:48 +0000 stat.datacount.accesslog: {"metric":"stat.2xx.count","value":55} 2015-03-08 15:36:48 +0000 stat.datacount.accesslog: {"metric":"stat.3xx.count","value":0} 2015-03-08 15:36:48 +0000 stat.datacount.accesslog: {"metric":"stat.4xx.count","value":6} 2015-03-08 15:36:48 +0000 stat.datacount.accesslog: {"metric":"stat.5xx.count","value":30}
以下のような設定を行った。
type copy type stdout type dd dd_api_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
事前に Datadog の API キーを取得しておくこと。
そして可視化
fluent-cat で…
以下のように fluent-cat
でデータを送信。
echo "{"status":"200","reqtime":"0.123","method":"GET","uri":"http://dev.hogehoge.test/v1/foo/bar?id=1"}" | /usr/lib64/fluent/ruby/bin/fluent-cat accesslog.`hostname`
上記のコマンドをそれぞれのホストで連続して実行すると…
直近一時間の状態
過去四時間の状態
type forest を利用してファイルに出力されたログ
以下のようなログが /tmp/fluent-${hostname}.log
に出力されている。
2015-03-08T16:26:44+00:00 accesslog.b1045fb1a7e0 {"status":"500","reqtime":"0.123","method":"GET","uri":"http://dev.hogehoge.test/v1/foo/bar?id=1"} 2015-03-08T16:26:46+00:00 accesslog.b1045fb1a7e0 {"status":"500","reqtime":"0.123","method":"GET","uri":"http://dev.hogehoge.test/v1/foo/bar?id=1"} 2015-03-08T16:26:48+00:00 accesslog.b1045fb1a7e0 {"status":"500","reqtime":"0.123","method":"GET","uri":"http://dev.hogehoge.test/v1/foo/bar?id=1"}
上記の accesslog.b1045fb1a7e0
の b1045fb1a7e0
はログを送信しているホスト名となる。
最後に
- fluentd-plugin-datacounter はレコードで指定したキーの値に対して正規表現でマッチさせてカウントするプラグインで Web サーバーのステータスコード等のカウントに利用出来る
- 更に fluentd-plugin-map は Ruby の map メソッド指定したキーの値を取得して新しいレコードを生成出来る
- fluentd-plugin-forest はレコードの内の値を利用してタグやファイル名を設定することが出来る
ということで、それぞれのプラグインを組み合わせることでログから取得した情報で簡単に可視化を行うことが出来そう。あと、プラグインの使い方と複数のプラグインの組み合わせによる相互作用等についても把握する必要があると痛感。
元記事はこちらです。
「fluentd 復習(1)〜 fluentd-plugin-datacounter と fluent-plugin-map や fluent-plugin-dd を使った可視化の例〜」