オートスケーリングみたいなことをしようとする場合、サービスインする前に監視が全て OK になっているかチェック しておきたいみたいな需要がありますが、みんな大好き Nagios でこれをやろうとするとちょっと面倒だったりします。
Nagios::StatusLog のようなものを使って status.dat
をパースする方法がお手軽ですが、監視するホストが数千台みたいな環境だと status.dat
が結構な大きさになってしまい、必要なたびにパースしてると Nagios が動いてるホストが結構なメモリを喰って swap に入ってしまったり、他のホストに転送してパースするにしてもそれなりに帯域喰ってしまうので、Nagios のホスト上で status.dat
をパースして一定期間キャッシュし、HTTP でよしなに JSON を返してくれればいいなとか思っていたら、nagira でそれが実現できそうだったので試してみました。
ちなみに nagira
は NAGIos Restful Api
を意味しているようです。
インストール
nagira
は Sinatra
なアプリなので、bundler
で適当な場所にインストールします。
git clone https://github.com/dmytro/nagira.git
cd nagira
bundle install --path vendor/bundle --binstubs
nagira 自体には init スクリプトとかを準備してくれる仕組みがあって、conf は RHEL なら /etc/sysconfig/nagira
を見にいきますが、今回は daemontools を使いたかったので下記のような run ファイルを用意して、conf も /etc/nagira.conf
あたりにおいておきます。ちなみにキャッシュする時間は NAGIRA_TTL
で調整できるみたいです。
#!/bin/sh
exec 2>&1
export APP_ROOT=/path/to/nagira
export RACK_ENV=production
. /etc/nagira.conf
exec setuidgid nagios \
$APP_ROOT/bin/nagira
#
# Defaults configuration file for Nagira
# --------------------------------------------
#
# ----------------------
# Port. Default 4567
# ----------------------
NAGIRA_PORT=4567
#
# ----------------------
# BIND
# ----------------------
# String specifying the hostname or IP address of the interface to
# listen on when the :run setting is enabled. The default value –
# '0.0.0.0' – causes the server to listen on all available
# interfaces. To listen on the loopback interface only, use: 'localhost'
#
NAGIRA_BIND=0.0.0.0
#
# ----------------------
# Environment
# ----------------------
# Usually needs to be production
#
RACK_ENV=production
#
# ----------------------
# Nagira user
# ----------------------
# Usually nagira process should be run by same user ID as Nagios. In
# many cases this is nagios user.
#
NAGIRA_USER=nagios
#
# ----------------------
# RVM
# ----------------------
# RVM_STRING="rvm use default"
#
# ----------------------
# Log file
# ----------------------
NAGIRA_LOG=/path/to/nagira.log
#
# ----------------------
# TTL for data
# ----------------------
# Number of seconds between re-parses. All Nagios file are parsed no
# more often than this. Default is 5 sec. Setting this to 0 or
# negative number disables TTL and backgroiund prser as well.
#
NAGIRA_TTL=30
#
# ----------------------
# Background parsing
# ----------------------
# Set this to 0, to disable background parsing.
NAGIRA_BG_PARSING=1
#
# ----------------------
# Nagios configuration file
# ----------------------
# Where main Nagios configuration file is located. usually this does
# not need to change.
#
NAGIOS_CFG_FILE=/path/to/nagios.cfg
出力例
こんな感じで監視してるホストの一覧とか、サービスの状態が json で取得できるので色々と捗りそうです。ちなみに API はこの辺りに載っています。また、| python -mjson.tool
で json 渡すとよしなにやってくれることを昨日知りました。情弱ですいません。
curl -s http://nagios.example.com:4567/_status/_list | python -mjson.tool
[
"host0001",
"host0002",
"host0003",
"host0004",
"host0005",
"host0006",
"host0007",
"host0008",
"host0009",
"host0010",
]
curl -s http://nagios.example.com:4567/_status/host0001/_services | python -mjson.tool
{
"CPU": {
"acknowledgement_type": "0",
"active_checks_enabled": "1",
"check_command": "check_cpu!60",
"check_execution_time": "0.149",
"check_interval": "120.000000",
"check_latency": "0.211",
"check_options": "0",
"check_period": "24x7",
"check_type": "0",
"current_attempt": "1",
"current_event_id": "248",
"current_notification_id": "0",
"current_notification_number": "0",
"current_problem_id": "0",
"current_state": "0",
"event_handler_enabled": "1",
"failure_prediction_enabled": "1",
"flap_detection_enabled": "1",
"has_been_checked": "1",
"host_name": "host0001",
"is_flapping": "0",
"last_check": "1375751157",
"last_event_id": "243",
"last_hard_state": "0",
"last_hard_state_change": "1374725239",
"last_notification": "0",
"last_problem_id": "108",
"last_state_change": "1374725239",
"last_time_critical": "1374724999",
"last_time_ok": "1375751157",
"last_time_unknown": "1374725119",
"last_time_warning": "0",
"last_update": "1375751195",
"max_attempts": "3",
"modified_attributes": "0",
"next_check": "1375751277",
"next_notification": "0",
"no_more_notifications": "0",
"notification_period": "24x7",
"notifications_enabled": "1",
"obsess_over_service": "1",
"passive_checks_enabled": "1",
"percent_state_change": "0.00",
"plugin_output": "CPU OK : CPU(Usr) => 0 CPU(Sys) => 0 CPU(IOwait) => 1",
"problem_has_been_acknowledged": "0",
"process_performance_data": "1",
"retry_interval": "8.000000",
"scheduled_downtime_depth": "0",
"service_description": "CPU",
"should_be_scheduled": "1",
"state_type": "1"
},
まとめ
Nagios 自体がこの機能を提供してよと思うところもありますが、とりあえずこれでやりたいことは実現できそうなので、もう少し実践的な場面で試していきたい所存です。