|
|
|
|
運用サーバが死んでいたことに半日気付かなかった。当方、やんごとなき事情で ActiveRecord + DBI という変態プレイのために、ある程度のページ(AR)は動作するが、特定のページ(DBI)だけはエラーになるなんてことが稀に発生しちゃうのだ。エラーの原因は色々あって、なぜかある日突然接続できなくなったり、長期稼動時にFastCGIが腐っていたり、そもそもDBIのライブラリが消えてるという恐ろしいこともあった。(iDCがこっそり鯖を入れ替えたんじゃないのか?みたいな)。
で、そんな頻繁に起きるタイプの障害ではないのだが、最近立て続けに遭遇してしまったため、念のためにサーバを監視しておいた方がよさそうである。でも定期的にチェックするのも激しく面倒だし、そんな時間はない。2chや日記サイトとかは凄い頻度で見てるけどね。つーか、佐紀スレなんて5分おきにチェックして独占阻止してる気もするけど。。。いいの。それはいいの!とにかく、わざわざサーバを監視するのは何か面倒なの!何が違うんだろう。
ノノハヽ∩ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 川´・_・リ/< サーバの状態をRSSで見れるようにすればいいと思います __ / / \______________________ \⊂ノ ̄ ̄ ̄\ ||ヽ|| ̄ ̄ ̄ ̄ ̄|| ...|| 委員長 ||
フンガッ!!確かにそうすれば、頻繁なWebチェックの副作用で一緒にチェックできるんジャマイカ?
require 'rss/maker'
class StatusController < ApplicationController
######################################################################
### Check classes
class Check
def initialize (name = nil, &block)
@name = name || self.class.to_s
@check = block || Proc.new{ check }
end
attr_reader :name, :passed, :message, :checked_on
def execute
@passed = true
@checked_on = Time.now
@check.call
rescue Exception => err
@passed = false
@message = err.to_s
end
end
class ConnectViaDBI < Check
def check
config = ActiveRecord::Base.configurations[::RAILS_ENV]
adapter = "dbi:%s:%s" % [config['adapter'], config['database']]
require 'dbi'
DBI::connect(adapter, config['username'], config['password']).disconnect
end
end
class PeacefulDay < Check
def check
error_count = Syslog.count("DATEDIFF(NOW(),created_on) < 1 AND priority > 10")
raise "%d errors occurred !!" % error_count if error_count > 0
end
end
protected
def checks
[
Check.new("ライブラリ 'digest/md5'") { require 'digest/md5'},
Check.new("ActiveRecord からの接続") {ActiveRecord::Base.connection.active?},
ConnectViaDBI.new("DBI からの接続"),
PeacefulDay.new("今日も平和"),
]
end
public
######################################################################
### Actions
def index
render :inline=>"<%= auto_discovery_link_tag :rss, :action => 'rss' %>"
end
def rss
rss = RSS::Maker.make("1.0") do |maker|
error_count = 0
checks.each_with_index do |check, i|
check.execute
item = maker.items.new_item
item.link = url_for(:id=>i)
item.description = check.passed ? "OK" : "NG"
item.title = "[%s] %s" % [item.description, check.name]
item.content_encoded = check.message.to_s
item.date = check.checked_on
error_count += 1 unless check.passed
end
maker.channel.about = url_for
maker.channel.link = url_for
maker.channel.title = "[%s] %s" % [(error_count > 0) ? "NG":"OK", url_for(:controller=>'')]
maker.channel.description = "%d checks, %d failures" % [checks.size, error_count]
end
@headers["Content-Type"] = 'application/xml; charset=UTF-8'
render :text => rss, :layout => false
end
end |
みたいなのを速攻ででっち上げ。各サーバに置いてみた。

あら、意外とよさげじゃない。RSSリーダで直接見てもいいし、多サーバ&自動化するときの中間コードとしても使えそうだし。HEAD とかの単なる ping でなくて、自分の欲しい情報を自由に取得できるのがいい感じだ。使い方はCheckインスタンスに処理を渡すか、長ければサブクラス化して、checks メソッドの中に入れるだけ。よかったらどうぞ。
ふと嫌な予感がして、「RSS サーバ監視」あたりで検索してみたら「Montastic」というサーバ監視サービスがやっぱりありました。やはり凡人の考えなどお見通しですね。
アカウントは10秒で取得できて(*1)、AjaxなGUIでサーバを登録しておくと、異常があったらRSSやメールで通知してくれるみたいです。(メール送信先は5箇所指定可能)。そして、なにより無料なのが素晴らしいです。操作も直感的だし、Webでの確認ページも綺麗で好感触。
(*1) 項目も「メアド(通知用)」と「パスワード」のみ!
(↑存在しないページを指定してみた)
問題は、監視の更新のタイミングが指定できない点ぐらいかな。(10分固定?)。Webサーバの大筋の稼動状態はこれに任せて、マニアックなチェックはStatusControllerでやる、というハイブリッドな運用でしばらくやってみよう。
直接 GET してくるみたい。
209.61.157.78 - - [10/Feb/2006:16:11:36 +0900] "GET /xxx HTTP/1.1" 404 201 "-" "montastic-webmonitor"
| JRuby | Rails | Berryz | ℃-ute | エッグ | jQuery |
| 前 | 2006年 2月 |
次 | ||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | ||||