ようへいの日々精進XP

おっさんの日記です。

td-agent(fluentd) の monitor_agent で取得出来る情報を Graphite + Grafana で見る試み

どうも、かっぱです。

追記

Grafana を手動でポチポチがかったるそうだったので Scripted-dashboard試してみた。

はじめに

以前に td-agentmonitor_agent を利用してこんなことをやっていたことを記事をツイートして頂いたようでして...

汗...

決して競合とかになろうとか思ったわけではない(笑)のだけども、ツイート頂いたことに感謝しつつ、あまりの不出来さに恥ずかしくなりながらも、次期バージョンwwに向けて Rubytd-agent の勉強のつもりで取得出来る情報を Graphite と Grafana で可視化してみた。

尚、ちゃんとモニタリングしたい場合にはTreasure Agent Monitoring Serviceを使うと良いと思います!


monitor_agent についておさらい

monitor_agent は何をするのか?

上記を参考にすると...

  • HTTP 経由で JSON 形式の内部メトリックを取得できる監視エージェント
  • 24220 ポートで Listen する
  • LTSV 形式でも情報を取得することが出来る

どんな情報が取得出来るのか?

  • 各ホストで稼働している td-agent or fluentdプラグイン情報
  • output プラグインretry_count / buffer_total_queued_size / buffer_queue_length
  • 下記の td_monitor_agentemit_count も合わせて取得出来る

設定

以下を td-agent.conf に追加して td-agent を再起動するだけ。

<source>
  type monitor_agent
  bind 0.0.0.0
  port 24220
</source>

取得出来る情報

以下のように HTTP リクエストを投げると...

curl -s http://${TD_AGENT_HOST}:24220/api/plugins.json | jq .

/api/plugin.json でアクセスすると以下のように JSON でレスポンスが返ってくる。

{
  "plugins": [
    {
      "config": {
        "port": "24220",
        "bind": "0.0.0.0",
        "type": "monitor_agent"
      },
      "output_plugin": false,
      "type": "monitor_agent",
      "plugin_id": "object:3f9bf86637c0"
    },
    {
      "config": {
        "tag": "apache.access",
        "path": "/var/log/httpd/access_log",
        "format": "apache",
        "type": "tail"
      },
      "output_plugin": false,
      "type": "tail",
      "plugin_id": "object:3f9bf72eedd4"
    },

/api/plugin でアクセスすると以下のように LTSV でレスポンスが返ってくる。

plugin_id:object:3f9bf86637c0   type:monitor_agent      output_plugin:false
plugin_id:object:3f9bf72eedd4   type:tail       output_plugin:false
plugin_id:object:3f9bf72f09b8   type:copy       output_plugin:true
plugin_id:object:3f9bf72f0508   type:stdout     output_plugin:true
plugin_id:object:3f9bf72f0080   type:file       output_plugin:true      buffer_queue_length:0   buffer_total_queued_size:2384070        retry_count:0
plugin_id:object:3f9bf731bcf8   type:file       output_plugin:true      buffer_queue_length:0   buffer_total_queued_size:2384070        retry_count:0
plugin_id:object:3f9bf731ae48   type:s3 output_plugin:true      buffer_queue_length:0   buffer_total_queued_size:13183110       retry_count:0

Tresure Data が提供するモニタリングサービスについて

現時点ではベータ版となっているようだが Tresure Data がモニタリングサービスを提供している。

f:id:inokara:20140531064529p:plain

以下のようにホストのリソース情報も確認することが出来る。

f:id:inokara:20140531072133p:plain

設定は monitor_agent と同様 td-agent.conf に以下を追加してプロセスを再起動するだけで監視が開始される。(※apikey は事前にダッシュボードで取得しておく必要がある)

<source>
  type td_monitor_agent
  apikey xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  instance_id xxxxxxx
  disable_node_info true
</source>

disable_node_infotrue にしておくとホストのリソース情報以外の情報を送信する(デフォルトは false になっている)。また、instance_id を指定しない場合には td-agent.conf のパスが表示されるようなので必要に応じて instance_id は設定しておいた方がたくさんのホストを管理する場合には良いかと思われる。

詳細については...

を見る。


で、どうするの?

こんな感じで...

各処理をどの位の粒度でメソッド化すれば良いのかも解らず、変数のスコープについてもシェルスクリプト的な使い方になってしまっているので突っ込みどころ満載。

大きな壁

monitor_agentJSONLTSV で返ってくることは解ったが、そのレスポンスからプラグイン毎で retry_count / buffer_total_queued_size / buffer_queue_length を取得する(JSON をパースする)のが(自分にとって)至難の技であることは間違い無かったが試行錯誤の上で以下のようにした。

返ってきた JSONplugin に含まれる数(size メソッド)をプラグインの数として、そのプラグイン数分(実際には配列は 0 から始まるので取得したプラグイン数からマイナス 1 をする)のループ処理で JSON からプラグイン毎の必要な値を取得した。

Graphite へのメトリクスを投げる

これは意外に簡単だった。幾つか Gem が存在する中で以下の Gem を利用した。

require 'graphite-api' しておいて以下のようなメソッドで処理するようにした。

def post_graphite(host, type, rtc, bql, btqs)
  client = GraphiteAPI.new( graphite: $graphite_host )
  client.metrics(
    "#{host}.#{type}.retry_count"  => rtc,
    "#{host}.#{type}.buffer_queue_length"  => bql,
    "#{host}.#{type}.buffer_total_queued_size"  => btqs
  )
end

Graphite. ピリオドをメトリクスパスの区切りとして利用する為 host という変数は .- に変換する処理を行っている。

実際に Graphite には以下のように登録される。

f:id:inokara:20140531075832p:plain

Grafana だと...

以下のような感じになる。

f:id:inokara:20140531075900p:plain

ホストが増えてくると手動でポチポチするのが耐えられなくなると思われる...(そこで GrafanaScripted-dashboardsの出番だったりするのかな...)


最後に

  • JSON をパースして結果をどうこうするという勉強にはなったが、もっと効率とか見栄え、メンテナンスし易い書き方を模索したい

cloudwatch-agent というツールを作ったので cloudwatch-agent-chef というのも作った

はじめに

cloudwatch-agent というツールを前回作ったので、勢いで cloudwatch-agent-chef というのも作ってみた。


参考

@sawanobolyさん、いつも有難うございます。


メモ


インスタンスリソースをCloudWatch のカスタムメトリクスに投げるスクリプトを作ってみた

追記

リポジトリの名前を以下の通りに変えたのと初回のみ Alarm 設定が出来るようにしてみた。

上記をインスタンス上におく ChefCookbook も後からアップする予定。


何番煎じ?

か解らないくらいだが必要に迫られてインスタンスリソースをCloudWatch のカスタムメトリクスを投げるスクリプト書いた。

ググるJava 版の CLI ツールを使った例は良くみるのであえて Python 版のコマンドラインツールを利用することにした。


おソース

github

リソースと言っても

以下が取ってカスタムメトリクスに送る。

  • CPU 使用率
  • Load Average
  • メモリ使用量(メガ)
  • Root パーティションのディスク使用量(メガ)

こんな感じ

f:id:inokara:20140520072949p:plain


なんで CloudWatch なの?

なんで?

  • Sensu を導入しきれなかった
  • かと言って Zabbix とかを導入するまでも無い
  • もちろん課金はあるけどお手軽な CloudWatch の検証も兼ねて

CloudWatch について自分なりに調べた


スクリプト作成で目指したこと

  • 出来るだけ拡張しやすく
  • 必要に応じて取得したい内容をシェル関数で定義すれば拡張出来るかも

todo

  • メモリの空き容量についても監視する
  • ディスク容量監視を Root パーティション以外も監視出来るようにする
  • スワップ容量監視を追加したい
  • リソース以外にも稼働しているサービスの監視も出来るようにする

RabbitMQ クラスタ HA 3 パターンを速攻試す(2)

引き続き RabbitMQ のクラスタ HA モード

現時点では allexactly を試したが、言わずもがな all が最も耐障害性が高い。但し、同期のコストは高く、キューの数が多くなれば多くなる程ノードへの負荷も高くなると思われる。

あと、今まではピンと来なかったがキューは登録する(Publishers)だけではなく受取る(Consumers)側からも生成することが出来るので、Consumer に対して Publish するということももちろん出来る。

RabbitMQ オモロイ。

RabbitMQ クラスタ HA 3 パターンを速攻試す

涙の自腹課金検証シリーズはじめました

今までもちょいちょいやってたけどシリーズ化。AWS を自腹で課金しながら試すこの企画。第一弾は...

試す。

時間と課金、そして検証対象との勝負。ちなみに検証環境はコマ目にあげさげ(start/stop)すればそれほど課金されないと思うよ。

2014/05/06 の知ったかぶり

最近のトゥウィート

おおっ Infrataster

Web サーバーや Web アプリケーションの振る舞いをテスト出来そう。

ちなみに Infrataster の作者によるスライドは下記の通り。

GitHubリポジトリは以下の通り。

後で試してみる!

AWS CloudTrail が新しいサービスに対応した

AWS のコンソールや API 等の操作ログが取れる CloudTrail が新しいサービスに対応したようだ。まだ、東京リージョンでは利用出来ないのは残念...。


知ったかぶり

ChefHandlers という Chef Client の動作ログ等を取れるのでログを Graphite に飛ばして結果(掛かった時間や Chef のリソース数、成功、失敗の数等...)を可視化してみた。

JSON ファイルに書き出したり、IRC に飛ばしたり出力先は色々と選べるらしい。


2014/05/04 の知ったかぶり

最近のトゥウィート

Chef活用ガイド の書評

「Chef活用ガイド コードではじめる構成管理」の書評を書かれた方のトゥウィート。

自分も改めて読みたいと思います。

Sensu のステッカー!

おお。


知ったかぶり

既に Chef で構築されている方はいらっしゃるので、自分は Puppet 使って Sensu Server を構築してみました。後で Chef でも試してみたいと思います。

難しいことはありませんでしたが、マニフェストの書き方の問題ではないかと思うのですが一発では Sensu Server の起動まではしてくれませんでした。

2014/04/27 の知ったかぶり

ElastiCachememcachedクラスタを組む場合の引き続き。RDS for MySQL 5.6memcached プラグインを追加した状態で簡単なベンチマークを取得してみたり...。

とりあえずの見解としては単純なキャッシュ(アプリケーションのセッション情報のキャッシュとか)の用途としては RDS for MySQL 5.6 + memcached プラグインは向かないがクエリのキャッシュストレージとして利用した場合にはその力を発揮出来るかもしれない。

2014/04/26 の知ったかぶり

ElastiCachememcachedクラスタを組む場合の試行錯誤。

とりあえずの見解としては冗長構成をちゃんと取ろうとすると memcached はちょい辛いかなという印象。負荷の分散という意味では twemproxy という選択肢もアリ。

2014/04/25 の知ったかぶり

AWSElastic Beanstalk という PaaS 的なサービスで Docker が利用出来るようになったので試してみた。

とっても簡単に docker run までイケた。