バージョン 0.9 くらいのときの公式ドキュメントのざっくり訳+個人のメモ
情報が古い+理解が間違ってるとこあるかもなので注意して欲しいけど、需要がありそうなので出してみる
Overview
Sensu は監視ツールの一つ。Sensu はよく "monitoring router" と記述される。もっと平たく言うと、Sensu は多くのノードに対して "check" スクリプトを実行し、1 つまたは複数の Sensu サーバーにて "handler" スクリプトを実行する。
例えば、Apache の死活チェックをするとしよう。チェックスクリプトにより死活だけでなくメトリクスも収集する。そしてそのアウトプットは 1 つまたは複数の Handlers にルーティングされる。Handlers はチェック結果によって何をするのか定義するものだ。Handlers は今のところ E メール、IRC、Twitter にアラートを送ったり、Graphite, Librato などにメトリクスを渡すことができる。またチェックスクリプトやハンドラースクリプトはどんな言語で書いてもよい。
# router のイメージ
# 色々な監視結果を sensu が適切なハンドラーにルーティング
checks -> sensu -> handlers
作者 Sean Porter によるイントロダクション
Key details
- Ruby (EventMachine, Sinatra, AMQP), RabbitMQ, Redis
- travis-ci を通した CI と、高いテストカバレッジ率
- メッセージ志向アーキテクチャ。メッセージは JSON オブジェクト
- 既存の Nagios プラグインを再利用できる
- プラグイン、ハンドラー、チェックスクリプトはどんな言語で書いてもよい
- メトリクスを送るバックエンドは様々なものをサポート (Graphite, Librato, etc)
- Chef や Puppet のようなモダンな CM ツールを考慮した設計
- クラウド環境のための設計
- 1200 行程度で軽い
- "オムニバス"(多くの項目を扱う)スタイルパッケージ
Event Data とは
Event Data は
- Client info
- Check info
- いくつかの metadata
から構成される JSON データ。言語の縛りがなく人間にも読みやすい
Example
{
"client":{
"name": "host01",
"address": "10.2.1.11",
"subscriptions": [
"all",
"frontend",
"proxy"
],
"timestamp": 1326390159
},
"check":{
"name": "frontend_http_check",
"issued": 1326390169,
"output": "HTTP CRITICAL: HTTP/1.1 503 Service Temporarily Unavaliable",
"status": 2,
"command": "check_http -I 127.0.0.1 -u http://web.example.com/healthcheck.html -R 'pageok'",
"subscribers":[
"frontend"
],
"interval": 60,
"handler": "campfire",
"history": [
"0",
"2"
],
"flapping": false
},
"occurrences": 1,
"action": "create"
}
コンポーネント
Sensu Server
Sensu server は sensu client のチェック開始のトリガーとなります。そしてチェック結果の出力を受け取ると handlers にフィードします。(バージョン 0.9.2 では client は server が知らないチェックも行います)
Sensu server は persistent データの保持に Redis インスタンスを使います。また自分自身と sensu client のデータのやりとりにおいて RabbitMQ もヘビーに利用します。
Sensu client
Sensu client は監視したいサーバー上で実行する。Sensu client はチェックスクリプト (check_http
, check_load
etc) を実行し RabbitMQ を通して Sensu server に結果を返します。
Sensu API
Sensu server (Redis) 上の色々なデータへアクセスするための REST API 。普通は Sensu Server または Redis インスタンスと同じサーバーで実行します。
Sensu dashboard
現在の Sensu インフラとアラートなどのアクションの状態を表示する Web ダッシュボード
インストール
一般的には Sensu 環境には 2 種類のノードが必要になる。Sensu-Server にも Sensu-Client をインストールすることに注意
- Sensu Server
- RabbitMQ
- Redis
- Sensu-Server / Sensu-Client / Sensu-API / Sensu-Dashboard
- Sensu Client
- Sensu-Client
Chef (または Puppet ) を使っているなら既に recipe が用意されている。
Sensu Server の構築
Chef で構築する場合は、sensu / sensu-chef - Github を利用する。
sensu-chef をそのまま使うのではなくて、sensu-chef の recipe を include した wrapper cookbook を別に用意する。
Sensu Server の recipe。default handler がないと server が起動しないので適当に定義しておく
include_recipe "sensu"
include_recipe "sensu::rabbitmq"
include_recipe "sensu::redis"
sensu_handler "default" do
type "pipe"
command "ls"
end
include_recipe "sensu::api_service"
include_recipe "sensu::client_service"
include_recipe "sensu::dashboard_service"
include_recipe "sensu::server_service"
自分は chef-monitor という作者が作ってる wrapper cookbook のさらに wrapper cookbook を作って使っている
Chef なしで構築
Amazon Linux 上に sensu-server を構築する(1) 参考
起動方法
Sensu Server の起動
Sensu サービスを enable にして、
CentOS/REHL
sudo chkconfig sensu-server on
sudo chkconfig sensu-api on
sudo chkconfig sensu-client on
sudo chkconfig sensu-dashboard on
Debian/Ubuntu
update-rc.d sensu-server defaults
update-rc.d sensu-api defaults
update-rc.d sensu-clent defaults
update-rc.d sensu-dashboard defaults
起動
sudo /etc/init.d/sensu-server start
sudo /etc/init.d/sensu-api start
sudo /etc/init.d/sensu-client start
sudo /etc/init.d/sensu-dashboard start
Sensu Server WebUI は 8080 番ポート
設定
設定ファイル
主な設定ファイルは
/etc/sensu/config.json
また、
/etc/sensu/conf.d/
以下に置いたファイルも設定ファイルとして読み込まれる。
設定項目は
- Client 情報
- Handler 定義
- Mutator 定義
- Checks 定義
Sensu Server に必須の設定
Sensu Server は default handler が必ず必要になる。/etc/sensu/config.json
や /etc/sensu/conf.d/default_handler.json
に
"handlers": {
"default": {
"type": "pipe",
"command": "PATH/default"
}
}
を追加する。(default handler の中身は適宜変える)
Client Info
Client Info とは
- 各 Client はある定義、 Client Info を必要とする。
- Client info は監視サービスが起動された際に publish される
- これがどのように Sensu に client が登録されるかの仕組みとなる
必須 Client Info
Client info にはいくつかの指定必須 key-value がある。
- name - クライアント名
- address - クライアントの IP アドレス
- subscriptions - Roles のリストまたは Role 同等のもの
- 監視内容はこれに基づく
Example
{
"client": {
"name": "web00",
"address": "127.0.0.1",
"subscriptions": [
"production",
"webserver",
"mysql"
]
}
}
カスタム Client Info
Client info にはカスタム key-value を追加できる
{
"client": {
"name": "web00",
"address": "127.0.0.1",
"subscriptions": [
"production",
"webserver",
"mysql"
],
"mysql": {
"host": "localhost",
"port": 3306,
"user": "foo",
"password": "bar"
}
}
}
Handlers
Handlers とは
Event Data に基づくハンドリング。
といったことを行う。
/etc/sensu/config.json
や /etc/sensu/conf.d/default_handler.json
といったファイルに記述する
Handlers のタイプ
Pipe
Pipe は STDIN を通して Event Data を渡し、あるコマンドやスクリプトを実行する
Example
Handler スクリプト(/etc/sensu/handlers/file.rb
)
#!/usr/bin/env ruby
require "rubygems"
require "json"
# Read event data
event = JSON.parse(STDIN.read, :symbolize_names => true)
# Write the event data to a file
file_name = "/tmp/sensu_#{event[:client][:name]}_#{event[:check][:name]}"
File.open(file_name, "w") do |file|
file.write(JSON.pretty_generate(event))
end
Handler 定義
{
"handlers": {
"file": {
"type": "pipe",
"command" : "/etc/sensu/handlers/file.rb"
}
}
}
コマンドを実行するのではなくメールを送信するように修正してみる
{
"handlers": {
"mail": {
"type": "pipe",
"command" : "mail -s 'sensu event' email@address.com"
}
}
}
TCP
TCP handlers は TCP socket に Event data を書き込む
(この具体的な利用例として Sean Porter が言ってたのが、例えば application のあるポートに監視のステータスを送ることで、メンテナンスモードにサーバーが自律的に変わるとかができるようになるとか。色々広がりそう。)
Example
localhost:4242 の TCP socket へ event data を書き込む
{
"handlers": {
"tcp_socket": {
"type": "tcp",
"socket": {
"host": "127.0.0.1",
"port": 4242
}
}
}
}
UDP
UDP Handlers は UDP socket に Event data を書き込む
Example
localhost:2424 の UDP socket へ event data を書き込む
{
"handlers": {
"udp_socket": {
"type": "udp",
"socket": {
"host": "127.0.0.1",
"port": 2424
}
}
}
}
AMQP
AMQP handlers は AMQP exchange へ event data を publishing する
Example
{
"handlers": {
"amqp_exchange": {
"type": "amqp",
"exchange": {
"type": "topic",
"name": "events"
}
}
}
}
Ruby AMQP ライブラリについてはここを
Set
Handlers Sets は handler のグルーピングを行う。
- 1 つの event data を複数の handlers に渡す
- または単純にある handler の alias を作る
Example
{
"handlers": {
"default": {
"type": "set",
"handlers": [
"file",
"tcp_socket"
]
}
}
}
Handler 設定
Example
my_handler1
では、settings["handlers"]["my_handler1"]["custom_setting"]
という設定値を利用している。おそらく /etc/sensu/handlers/file.rb
にてその値を使う。
my_handler2
では、トップレベルのネームスペースにある settings["my_handler2"]["another_custome_setting"]
という設定値を利用している。おそらく /etc/sensu/handlers/file.rb
にてその値を使う。
handlers 定義(設定)
{
"handlers": {
"my_handler1": {
"type": "pipe",
"command": "/etc/sensu/handlers/file.rb",
"custom_setting": "custom_val"
},
"my_handler2": {
"type": "pipe",
"command": "/etc/sensu/handlers/file.rb",
"custom_setting": "custom_val"
}
},
"my_handler2": {
"conventional_configuration": "true",
"another_custome_setting": "some_custom_value"
}
}
深刻度のフィルタリング
Handlers はある深刻度のときだけ実行する、といった事が可能だ。
Example
PagerDuty handler は Event が check の結果が 2 である CRITICAL または OK の時だけ実行する定義(設定)
{
"handlers": {
"pagerduty": {
"type": "pipe",
"command": "/etc/sensu/handlers/pagerduty.rb",
"severities": [
"critical",
"ok"
]
}
}
}
Mutators
Mutators とは
特定の handler に渡す前に event data を mutate(= 変異させる) もの。
cat event.json | mutator.rb | handler.rb
Mutators の例
event data (JSON データ) に、:mutated => true, :its_a_tumor => true
という key-value をマージさせる。(mutate 済みというタグを付ける例)
Event mutator (/etc/sensu/mutators/tag.rb
)
#!/usr/bin/env ruby
require "rubygems"
require "json"
# Read event data
event = JSON.parse(STDIN.read, :symbolize_names => true)
# Add a 'tag' to prove it has been mutated
event.merge!(:mutated => true, :its_a_tumor => true)
# Output mutated event data to STDOUT
puts event.to_json
Mutator 定義 (設定)
{
"mutators": {
"tag": {
"command": "/etc/sensu/mutators/tag.rb"
}
}
}
特定の Handler に mutator を使う
{
"handlers": {
"file": {
"type": "pipe",
"mutator": "tag",
"command": "/etc/sensu/handlers/file.rb"
}
}
}
ビルトイン mutators
mutator 定義をしなくても利用できるビルトイン mutators がいくつかある。
- Only check output
Checks
Checks とは
- Checks とはサービス状態をモニタリング・メトリクスの収集する Check スクリプトのこと。
- Checks は Sensu-Client によって実行される。
- 実行タイミングは Sensu-Server が握っている(設定ファイルに記述)
- Sensu-Server が定期的に Check 定義に紐づく Subscriptions を持つ client へ publish する(Check スクリプト実行の指示)
- Checks はコマンドまたはスクリプト
- STDOUT / ERR に出力する
- 終了コードを持つ
-
0
: OK -
1
: WARNING -
2
: CRITICAL -
3
: UNKNOWN or CUSTOM
-
この仕様は Nagios と互換性があるので、Nagios plugins をそのまま利用できる。
Checks Example
Check plugin (/etc/sensu/plugins/check-chef-client.rb
)
procs = `ps aux`
running = false
procs.each_line do |proc|
running = true if proc.include?('chef-client')
end
if running
puts 'OK - Chef client daemon is runnig'
exit 0
end
else
puts 'WARNING - Chef client daemon is NOT running'
exit 1
end
Check 定義 (設定)
{
"checks": {
"chef_client": {
"command": "check-chef-client.rb",
"subscribers": [
"production"
],
"interval": 60
}
}
}
定義内容
-
chef_client
: 一意な Check 名 -
command
: 実行する Check スクリプト -
subscribers
: どの subscriptions で Check を実行するか -
interval
: Check スクリプトを実行する間隔(秒)
どのように Check 結果が Event を生成するか
- デフォルトでは Check スクリプトの終了コードが 0 以外のとき、event が生成される
Handler ルーティング
- handler の指定がなければデフォルトで
default
handler へルーティングされる - handler は
"handler": "foo"
のように指定する- 複数ある場合は、
"handlers": ["foo", "bar"]
とする
- 複数ある場合は、
Example
Check 定義(設定)
{
"checks": {
"chef_client": {
"command": "check-chef-client.rb",
"subscribers": [
"production"
],
"interval": 60,
"handlers": [
"pagerduty",
"irc"
]
}
}
}
メトリクス Checks
Sensu の Checks における決まりとして構造データの出力先を STDOUT にする、というのがある。なのでメトリクス収集エージェントも利用できる。
- 終了コード
0
にて event を発生させるため、"type": "metric"
を checks 定義に追加する
Example
Check 定義 (/etc/sensu/plugins/cpu-usage-metrics.sh
)
#!/bin/bash
SCHEME=`hostname`
usage()
{
cat <<EOF
usage: $0 options
This plugin produces CPU usage (%) using /proc/stat
OPTIONS:
-h Show this message
-s Metric naming scheme, text to prepend to cpu.usage
EOF
}
while getopts "hs:" OPTION
do
case $OPTION in
h)
usage
exit 1
;;
s)
SCHEME="$OPTARG"
;;
?)
usage
exit 1
;;
esac
done
get_idle_total()
{
CPU=(`cat /proc/stat | grep '^cpu '`)
unset CPU[0]
IDLE=${CPU[4]}
TOTAL=0
for VALUE in "${CPU[@]}"; do
let "TOTAL=$TOTAL+$VALUE"
done
}
get_idle_total
PREV_TOTAL="$TOTAL"
PREV_IDLE="$IDLE"
sleep 1
get_idle_total
let "DIFF_IDLE=$IDLE-$PREV_IDLE"
let "DIFF_TOTAL=$TOTAL-$PREV_TOTAL"
let "DIFF_USAGE=(1000*($DIFF_TOTAL-$DIFF_IDLE)/$DIFF_TOTAL+5)/10"
echo "$SCHEME.cpu.usage $DIFF_USAGE `date +%s`"
check スクリプトはこんな出力をする
foo.cpu.usage 4 1350486269
Check 定義(設定)
{
"checks": {
"cpu_usage_metrics": {
"type": "metric",
"command": "cpu-usage-metrics.sh",
"subscribers": [
"production"
],
"interval": 10
}
}
}
Standalone Checks
Standalone Checks は Sensu-Client 自身によってスケジューリングされる Check 。
- 定義された client ではどの client でもスケジューリングされ実行される
- つまり subscriptions と無関係に実行されるということ
-
"standalone": true
を Check 定義に追加し、"subscribers"
を取り除く
Examples
Check 定義(設定)
{
"checks": {
"cpu_usage_metrics": {
"type": "metric",
"command": "cpu-usage-metrics.sh",
"standalone": true,
"interval": 10
}
}
}
Check コマンドへ引数を渡す
client 情報のカスタム key-value を利用する
Example
カスタム key-value mysql.user
と mysql.password
を利用する
Check 定義(設定)
{
"checks": {
"chef_client": {
"command": "check-mysql-replication.rb --user :::mysql.user::: --password :::mysql.password:::",
"subscribers": [
"mysql"
],
"interval": 60
}
}
}
カスタム Check 定義 key-value
Check 定義にもカスタム key-value を追加することができる。これにより、handler をよりクリエイティブにできる。
よくやるのは、"occurrences"
という、「何度発生したら handler が動くようにするかの最低回数」を追加する
Example
Check 定義(設定)
{
"checks": {
"chef_client": {
"command": "check-chef-client.rb",
"subscribers": [
"production"
],
"interval": 60,
"occurrences": 2
}
}
}
Flap 検知
Check の結果が "頻繁に" 変化しすぎるとき(監視設定が悪かったりネットワークの問題だったり)、"flapping": true
を Event Data に追加することができる。
flapping マークが着いた Event は flapping が解消するまでマークは消えない。
Example
Check 定義(設定)
{
"checks": {
"chef_client": {
"command": "check-chef-client.rb",
"subscribers": [
"production"
],
"interval": 60,
"low_flap_threshold": "5",
"high_flap_threshold": "25"
}
}
}
Extensions
大量のトラフィックに対して handling, mutating を行うときに有効
コミュニティプラグイン
コミュニティにて開発されている handlers / plugins (check script) が置いてある。
Tips
Sensu Admin
モバイル対応済みの WebUI
Uchiwa
uchiwa
Node.js ベースのリアルタイム WebUI 。データベースいらずで気軽。
デバッグ
ログ一覧
/var/log/sensu/
sensu-api.log
sensu-client.log
sensu-dashboard.log
sensu-server.log
〜が立ち上がらない
- Redis, RabbitMQ
- Sensu-Server
- Sensu-API
- Sensh-Dashboard
の順で起動するので、先に起動しておくべきものが起動してなかったり、
起動してるけど接続出来てなかったり。
/etc/sensu/config.json の rabbitmq や redis への接続先や iptables など
AWS だと、Redis, RabbitMQ, API のポートを空けておかないといけない
monitor cookbook メモ
- checks
- plugin は cookbook file
- config は data bag (sensu_checks)
- hanlers
- script は cookbook file
- config は recipe (Ex.) _graphite_handler.rb
- set config は attributes (Ex.) metrics set を作りたい時は sensu.handlers.metrics = ["a", "b"]
- chef-monitor の _graphite_handler.rb の bug
関連リンク / 参照
- sensu / sensu - GitHub
- 公式ドキュメント
- sensu-admin - GitHub
- Graphite
- Giraffe
- statsD
- flpjck / flapjack
- 通知をルーティングしてくれる OSS
- Sensu の Community Plugin の一覧
- Sensuを使って自由度の高い監視システムの構築を行う方法
- ようへいの日々精進 XP sensu カテゴリ
- FAQ 日本語
- 監視ソフトをNagiosからSensuに切り替えて2ヶ月経ったのでまとめた
- Sensuを使ってクラウド環境の監視を効率よく行おう
- iOS アプリ期待!