share facebook facebook2 twitter menu hatena pocket slack

2014.06.24 TUE

Sensu の standalone check について自分の理解を正す

川原 洋平

WRITTEN BY川原 洋平

cloudpack の 自称 Sensu芸人 の かっぱこと 川原 洋平@inokara)です。


はじめに

sensucheck には standalone というクライアント自身で監視イベントを発生させて結果だけを通知するモードが存在します。使い方としては、以下のように各種チェックの設定に standalone: true を入れるだけです。

{
  "checks": {
    "cron_check": {
      "handlers": ["default"],
      "command": "/etc/sensu/plugins/check-procs.rb -p crond -C 1 ",
      "interval": 60,
      "standalone": true
    }
  }
}

ただ、この standalone モードについてちゃんと理解出来ていなかったので改めてソースコード等を見ながら自分自身の理解を正していきたいと思います。



まずは


やっぱりこの図から

sensu-standalone-check_01
http://sensuapp.org/docs/0.12/overview より引用


各コンポーネント

各々のコンポーネントを簡単にまとめます。


Redis

  • sensu-server から届いた監視結果を保存する
  • 個人的には保存というより状態を留めておくようなイメージ
  • sensu APIからも情報を取得する


sensu-server

  • RabbitMQ に対して各クライアントに対して「監視しろ!」というキューを投げる
  • RabbitMQ から各クライアントの監視結果を取得して Redis に保存、合わせて各 Handler に処理させる(ここ重要)


sensu-api

  • Redis から情報を取得して各 API クライアントに情報を返す
  • API クライアントは sensu-dashiboardSensu Adminuchiwa


RabbitMQ

  • 現状では Sensu の中核を担う
  • sensu-server からの監視依頼キューを受け取ってクライアントに監視を実行させる
  • sensu-client から受け取った監視結果のキューを sensu-server に送る


sensu-client

  • sensu-server から RabbitMQ 経由で受けた監視依頼を忠実に実行する
  • 監視結果は RabbitMQ に返す
  • standalone モードが有効な場合には sensu-server からの監視依頼に関係なく自律して interval の間隔で監視を行い結果を RabbitMQ に返す


sensu-client のソース探訪

以下の疑問をもとに sensu-client のソースを見ていきます。


疑問

  • 監視結果はどんな風に処理しているのか?
  • standalone モードが有効な場合はどんな処理になるのか?


ソースコード


疑問(1)監視結果はどんな風に処理しているのか?

監視結果の処理はこのあたりのメソッドが該当するようです。

    def publish_result(check)
      payload = {
        :client => @settings[:client][:name],
        :check => check
      }
      @logger.info('publishing check result', {
        :payload => payload
      })
      @transport.publish(:direct, 'results', MultiJson.dump(payload)) do |info|
        if info[:error]
          @logger.error('failed to publish check result', {
            :payload => payload,
            :error => info[:error].to_s
          })
        end
      end
    end

インスタンス変数 @transportpublish というメソッドで処理されるようです。この @transport というインスタンス変数は sensu-transport から引き回されてる(こういう言い方で正しいかわからないけど)ので結果そのものは上記の図で言うところの transport 層(現状では RabbitMQ)で処理されることが判ります。

尚、RabbitMQ 視点だと以下のように Exchangeresults があるのが判ります。

sensu-standalone-check_02

なるほど。


疑問(2)standalone モードが有効な場合はどんな処理になるのか?

standalone モード周りの処理はこちらあたりのメソッドが担当しているようです。

    def setup_standalone
      @logger.debug('scheduling standalone checks')
      standard_checks = @settings.checks.select do |check|
        check[:standalone]
      end
      extension_checks = @extensions.checks.select do |check|
        check[:standalone] && check[:interval].is_a?(Integer)
      end
      schedule_checks(standard_checks + extension_checks)
    end

設定ファイル(JSON)の check から standalonetrue だった場合に interval の時間でチェックするように schedule_checksメソッドを叩いているようです。そして、この schedule_checksこのあたりEM::Timer.new あたりで監視イベントを発生させているのが判ります。


そして話題は EM クラスってなんぞやに…

そもそも EM クラスとはなんぞやはまたの機会に…ちなみにこれは sensu-em という gem が暗躍しているようです…。



まとめと反省


勘違いしてました

  • standalone モードでは RabbitMQ に対して結果は投げないとばかり思ってました
  • 上のアーキテクチャ図を見ればそんなこと無いのは一目瞭然にも関わらず…
  • すいませんでした!


まとめ

  • standalone:true の場合でも RabbitMQ に対して結果を投げる
  • 但し、監視イベントの発生はクライアント自身となる

元記事は、こちら