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

notebook

都内でWEB系エンジニアやってます。

fluentd + dstat + growthforecastではまったところ

fluentd + growthforecast + dstat

AWSの環境だとcloudwatchは2週間しかデータもてないので長期的にグラフが見たい場合に困ります

そこで、お手軽にできそうなfluentd + dstat + growthforecastを試してみようってことで、そのときのメモ

fluentd

fluentdをインストール

curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh

dstat

dstatをインストール

yum install dstat

growthforecastのセットアップ

別サーバを用意して起動しておく

pluginをインストール

使用するプラグインをインストール

# アプリサーバ
/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-dstat
/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-map
/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-record-reformer
/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-flatten-hash
# 集約、転送用サーバ
/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-growthforecast

パターン1-設定

最初はmapプラグインでgrowthforecastへ送るデータを一つ一つ精査して設定してみました

<match dstat>
  type map
  tag "monitor.dstat"
  time time
  record {"cpu.usr"=>record["dstat"]["total cpu usage"]["usr"],"cpu.sys"=>record["dstat"]["total cpu usage"]["sys"],"cpu.idle"=>record["dstat"]["total cpu usage"]["idl"],"cpu.wait"=>record["dstat"]["total cpu usage"]["wai"],"cpu.hiq"=>record["dstat"]["total cpu usage"]["hiq"],"cpu.siq"=>record["dstat"]["total cpu usage"]["siq"],"memory.used"=>record["dstat"]["memory usage"]["used"],"memory.buffer"=>record["dstat"]["memory usage"]["buff"],"memory.cache"=>record["dstat"]["memory usage"]["cach"],"memory.free"=>record["dstat"]["memory usage"]["free"],"loadaverage.1m"=>record["dstat"]["load avg"]["1m"],"loadaverage.5m"=>record["dstat"]["load avg"]["5m"],"loadaverage.15m"=>record["dstat"]["load avg"]["15m"],"disc.read"=>record["dstat"]["dsk/total"]["read"],"disc.write"=>record["dstat"]["dsk/total"]["writ"],"swap.used"=>record["dstat"]["swap"]["used"],"swap.free"=>record["dstat"]["swap"]["free"],"network.recieve"=>record["dstat"]["net/total"]["recv"],"network.send"=>record["dstat"]["net/total"]["send"],"udp.listen"=>record["dstat"]["udp"]["lis"],"udp.established"=>record["dstat"]["udp"]["act"],"tcp.listen"=>record["dstat"]["tcp sockets"]["lis"],"tcp.established"=>record["dstat"]["tcp sockets"]["act"],"tcp.syn"=>record["dstat"]["tcp sockets"]["syn"],"tcp.tim"=>record["dstat"]["tcp sockets"]["tim"],"tcp.clo"=>record["dstat"]["tcp sockets"]["clo"] }
</match>

一応動くには動いたけど、dstatのオプション変えたときにそちらも変えないといけなくなるため微妙、そして長すぎて読みづらいため他の方法を考えることに

パターン2-設定

そこで、思いついたのは下記

<source>
  type dstat
  tag dstat
  option -cdlmns --tcp --udp
  delay 5
</source>

# hostnameなどを除外、後のflatten_hashで"dstat"をキーに含めないために使用
<match dstat>
  type map
  tag "map.dstat"
  time time
  record record["dstat"]
</match>

# ネストしたデータをフラットにしてくれる
# {
#   "foo": { "bar": "aaa" },
#   "fuga": "piyo",
# }
# ↓
# { "foo.bar": "aaa", "fuga": "piyo" }
<match map.dstat>
  type flatten_hash
  tag flat.dstat
  separator .
</match>

# タグにホスト名を追加
<match flat.dstat>
  type record_reformer
  tag dstat.${hostname}
</match>

# growthforecastに送信
<match dstat.*>
  type copy
  <store>
    type file
    path /var/log/td-agent/dstat
  </store>
  <store>
    type growthforecast
    gfapi_url http://192.168.70.12:5125/api/
    service local
    tag_for section
    name_key_pattern .*
  </store>
</match>

record_reformerをホスト名追加のためだけに使ってるのはちょっと微妙だけどとりあえず。。。

これでOK!!かと思い起動!!

ぱっと見グラフにも出てるしういってるように見えたのですが、一個問題がありました。。。。

2014-10-18 20:09:16 +0000 [warn]: failed to post to growthforecast: 192.168.70.12:5125/api/local/dstat.web7/net/total.send, post_data: number=9473&mode=gauge code: 404

そうです、dstatで取得した文字列をレコードのキーとしたのでスラッシュが入ってしまってました

上記で言うと「net/total.send」までがnameセクションとして扱って欲しいのですが、growthforecastに投げる時、スラッシュをnameセクションの一部ではなくパスの区切りと認識されてしまいうまくリクエストできないのが原因でした

これ、いろいろ調べたものの、設定だけで何とかする方法が見つけられず、あえなくgrowthforecastのプラグインに直接処理を加えるという暴挙に出ることでいったん解決しました。

# ポストするキーを設定しているところで下記行を追加
key = key.gsub("\/","")

この問題に対してこれまでに試した事などを下記に残しておきます

record_reformer

  • remove_keysでnet/totalを削除し追加でnet-totalみたいな感じでレコードを追加する

問題

record_reformerの機能として既存のレコードを変数として呼び出せるのですが、今回の件だと「/」が入っているとうまく取得できず断念。。。

ちなみに「.」も含まれているとうまくレコードの中身を読み込めない模様

growthforecast

growthforecast側でレコードのキーを置換する機能は無いかなと捜してみましたが無い模様

flatten_hash

flatten_hash側でそういうことできるかと探してみたけどこちらも無い模様

最後に

こういうパターンでいい方法知ってる方がいたら教えていただきたいです。

それにしても、プラグインによってタグ名にクォートつけなくてはいけなかったり微妙に挙動が違ったりしてなんか大変。。。