読者です 読者をやめる 読者になる 読者になる

Studio3104::BLOG.new

uninitialized constant Studio3104 (NameError)

fluent-plugin-graphite を書いたよ

graphite にメトリクスをポストする fluent-plugin を書きました
先に github で公開されていた fluent-plugin-graphite がありましたが、イチから書いて gem release いたしました

https://github.com/studio3104/fluent-plugin-graphite
http://rubygems.org/gems/fluent-plugin-graphite

なぜイチから書いたのか

以下のような箇所に懸念があり、修正だと結局まるっと書き直すのと変わらないと思いイチから書いてしまいました

  • 先行プラグインは、
    • Fluent::BufferedOutput を継承し、内部でサンプリングやカウントなどの計算をしていたが、そういうのは他のプラグインに任せて、来た値をそのまま投げてあげればいいのではないかと思った
    • レコードの key というフィールドと、設定の key_prefix からグラフ名を生成し、 count, gauge というフィールドに値を入れなければならず、少し扱いにくさを感じた
    • メトリクスを送信するたびに TCP コネクションの切断、切断をしていた

新しく書いたプラグインの機能

詳しくは README を見ていただきたく

  • メトリクスを持つフィールドを指定して出力対象とする
  • グラフ名はタグと出力対象のフィールドのキーから生成
  • TCP コネクションを可能な限り使いまわす (graphite-api.gem による機能)
  • バッファリングしておいてある程度まとめてメトリクスを送信 (graphite-api.gem による機能)

たとえば dstat からグラフを生成したい場合

こんな感じの設定をすると、

<source>
  type dstat
  tag dstat.__HOSTNAME__
  option -lnc
  delay 3
</source>

<match dstat.**>
  type flatten_hash
  add_tag_prefix graphite.
  separator .
</match>

<match graphite.dstat.**>
  type graphite
  host localhost
  port 2003
  tag_for prefix
  remove_tag_prefix graphite.dstat.
  name_key_pattern ^((?!hostname).)*$
</match>

こんな感じのグラフが出来る

f:id:studio3104:20140408153558p:plain

先行プラグインとの互換性

設定ファイルを頑張って書きなおしてもらえれば同じグラフに対してメトリクスを送るようには出来ます
先日の このエントリ を例にすると、以下の様に設定ファイルを書き換えてあげる必要があります

<source>
  type dstat
  tag dstat
  option -lcn
  delay 5
</source>
 
<match dstat>
  type copy
  <store>
    type map
    tag  "map.dstat.gauges." + record["hostname"]
    time time
    record { "loadavg-short" => record["dstat"]["load avg"]["1m"] }
  </store>
  <store>
    type map
    tag  "map.dstat.gauges." + record["hostname"]
    time time
    record { "cpu-usr" => record["dstat"]["total cpu usage"]["usr"] }
  </store>
  <store>
    type map
    tag  "map.dstat.gauges." + record["hostname"]
    time time
    record { "cpu-sys" => record["dstat"]["total cpu usage"]["sys"] }
  </store>
  <store>
    type map
    tag  "map.dstat.gauges." + record["hostname"]
    time time
    record { "cpu-hiq" => record["dstat"]["total cpu usage"]["hiq"] }
  </store>
  <store>
    type map
    tag  "map.dstat.gauges." + record["hostname"]
    time time
    record { "cpu-siq" => record["dstat"]["total cpu usage"]["siq"] }
  </store>
  <store>
    type map
    tag  "map.dstat.gauges." + record["hostname"]
    time time
    record { "net-recv" => record["dstat"]["net/total"]["recv"] }
  </store>  
  <store>
    type map
    tag  "map.dstat.gauges." + record["hostname"]
    time time
    record { "net-send" => record["dstat"]["net/total"]["send"] }
  </store>  
</match>
 
<match map.dstat.**>
  type              graphite
  host              localhost
  port              2003
  remove_tag_prefix map
  name_key_pattern  .+
</match>