cloudpack の 自称 Sensu芸人 の かっぱこと 川原 洋平(@inokara)です。
はじめに
sensu の check には standalone というクライアント自身で監視イベントを発生させて結果だけを通知するモードが存在します。使い方としては、以下のように各種チェックの設定に standalone: true を入れるだけです。
{
"checks": {
"cron_check": {
"handlers": ["default"],
"command": "/etc/sensu/plugins/check-procs.rb -p crond -C 1 ",
"interval": 60,
"standalone": true
}
}
}
ただ、この standalone モードについてちゃんと理解出来ていなかったので改めてソースコード等を見ながら自分自身の理解を正していきたいと思います。
まずは
やっぱりこの図から
http://sensuapp.org/docs/0.12/overview より引用
各コンポーネント
各々のコンポーネントを簡単にまとめます。
Redis
- sensu-server から届いた監視結果を保存する
- 個人的には保存というより状態を留めておくようなイメージ
- sensu APIからも情報を取得する
sensu-server
- RabbitMQ に対して各クライアントに対して「監視しろ!」というキューを投げる
- RabbitMQ から各クライアントの監視結果を取得して Redis に保存、合わせて各 Handler に処理させる(ここ重要)
sensu-api
- Redis から情報を取得して各 API クライアントに情報を返す
- API クライアントは sensu-dashiboard や Sensu Admin や uchiwa 等
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
インスタンス変数 @transport の publish というメソッドで処理されるようです。この @transport というインスタンス変数は sensu-transport から引き回されてる(こういう言い方で正しいかわからないけど)ので結果そのものは上記の図で言うところの transport 層(現状では RabbitMQ)で処理されることが判ります。
尚、RabbitMQ 視点だと以下のように Exchange に results があるのが判ります。
なるほど。
疑問(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 から standalone が true だった場合に interval の時間でチェックするように schedule_checks のメソッドを叩いているようです。そして、この schedule_checks のこのあたりの EM::Timer.new あたりで監視イベントを発生させているのが判ります。
そして話題は EM クラスってなんぞやに…
そもそも EM クラスとはなんぞやはまたの機会に…ちなみにこれは sensu-em という gem が暗躍しているようです…。
まとめと反省
勘違いしてました
- standalone モードでは RabbitMQ に対して結果は投げないとばかり思ってました
- 上のアーキテクチャ図を見ればそんなこと無いのは一目瞭然にも関わらず…
- すいませんでした!
まとめ
- standalone:true の場合でも RabbitMQ に対して結果を投げる
- 但し、監視イベントの発生はクライアント自身となる
元記事は、こちら