share facebook facebook2 twitter menu hatena pocket slack

2015.03.17 TUE

fluentd 復習(1)〜 fluentd-plugin-datacounter と fluent-plugin-map や fluent-plugin-dd を使った可視化の例〜

川原 洋平

WRITTEN BY川原 洋平

ども、 cloudpackかっぱ (@inokara) です。

はじめに

蓋を開けると…

fluentd を全然使いこなせていないでちょっとずつ復習を兼ねて使ったことないプラグインを使ってみる。今回は fluent-plugin-datacounter を使ってみる。

ゴール

今回は fluent-plugin-datacounter を利用して各ホストから送信されるレコードに含まれるキーの値を集計して Datadog で可視化するまで。
fluent-plugin-datacounter で集計して Datadog で可視化するまでのイメージ図
図で表すと上のような流れにしたい。

fluent-plugin-datacounter とその他、今回登場するプラグイン

参考

fluent-plugin-datacounter

fluent-plugin-forest

fluent-plugin-map

  • tomity/fluent-plugin-map · GitHub
  • 特定のフィールド内容を Ruby を利用して加工するプラグイン
  • レコードに対して Ruby の map メソッドを使ってレコード内のキーを指定し値を取り出して加工するプラグイン(だと思う)

fluent-plugin-ddは

それぞれの設定

構成

以下のような構成で動作確認。
fluent-plugin-datacounter で集計して 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"}"

以下のような設定を行った。

<match accesslog.**>
  type copy
  <store>
    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
  </store>
  <store>
    type forest
    subtype copy
    <template>
      <store>
        type file
        path /tmp/fluent-${tag_parts[1]}.log
      </store>
    </template>
  </store>
</match>

<match datacount.accesslog>
  type copy
  <store>
    type map
    map ["stat." + tag, time, {"metric" => "stat.404.count","value" => record["404_count"].to_i}]
  </store>
  <store>
    type map
    map ["stat." + tag, time, {"metric" => "stat.2xx.count","value" => record["2xx_count"].to_i}]
  </store>
  <store>
    type map
    map ["stat." + tag, time, {"metric" => "stat.3xx.count","value" => record["3xx_count"].to_i}]
  </store>
  <store>
    type map
    map ["stat." + tag, time, {"metric" => "stat.4xx.count","value" => record["4xx_count"].to_i}]
  </store>
  <store>
    type map
    map ["stat." + tag, time, {"metric" => "stat.5xx.count","value" => record["5xx_count"].to_i}]
  </store>
  <store>
    type stdout
  </store>
</match>

ポイントとしては…

  • count_key status でカウントするキー status を指定
  • patternx xxx ^xdd$ でカウントする値を正規表現で指定
  • aggregate alltype datacounter を通過する全てのタグのレコードを対象とすることを指定
  • type map では Ruby でハッシュを扱う際にキーを指定して値を取得する感じで各キーの値を取得、さらに type dd で Datadog にレコードを送る際に {"metric":"xxx.xxx.xxx", "value": NN} というフォーマットで送信する必要があるのでそのように配列を生成している
  • type forestdatacounter で処理される前の状態のレコードをホスト毎にファイルに書き出す設定を行っている(type foresttype 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}

以下のような設定を行った。

<match stat.datacount.accesslog>
  type copy
  <store>
    type stdout
  </store>
  <store>
   type dd
   dd_api_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  </store>
</match>

事前に 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`

上記のコマンドをそれぞれのホストで連続して実行すると…

直近一時間の状態

fluent-plugin-datacounter で集計して Datadog で可視化するまで: 動作確認 (1) 直近一時間の状態

過去四時間の状態

fluent-plugin-datacounter で集計して Datadog で可視化するまで: 動作確認 (2) 過去四時間の状態

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.b1045fb1a7e0b1045fb1a7e0 はログを送信しているホスト名となる。

最後に

  • fluentd-plugin-datacounter はレコードで指定したキーの値に対して正規表現でマッチさせてカウントするプラグインで Web サーバーのステータスコード等のカウントに利用出来る
  • 更に fluentd-plugin-map は Ruby の map メソッド指定したキーの値を取得して新しいレコードを生成出来る
  • fluentd-plugin-forest はレコードの内の値を利用してタグやファイル名を設定することが出来る

ということで、それぞれのプラグインを組み合わせることでログから取得した情報で簡単に可視化を行うことが出来そう。あと、プラグインの使い方と複数のプラグインの組み合わせによる相互作用等についても把握する必要があると痛感。

元記事はこちらです。
fluentd 復習(1)〜 fluentd-plugin-datacounter と fluent-plugin-map や fluent-plugin-dd を使った可視化の例〜