2013年1月25日金曜日

ZFSの障害発生をメールで自動通知

ほったらかしにしてたら1ヶ月経ってしまった。
筆が遅くて数十分でブログネタ一本書いたりとかできないタイプなので、
ちょーっと忙しくなると(優先順位が低いだけに)放置しがちである。

というわけで(?)今回は軽いネタ。
表題の通りZFSが動いてるサーバーでディスクが逝ったなどの障害が起こった際に指定したメールアドレスへ障害発生通知を送ってもらいましょう。それだけ。
「ん?mailコマンドで送って終了だろ?」で終了といえば終了だが、サーバーが動いている家のプロバでは(多分)OP25Bとやらでローカルからメールが送れないので、OP25Bを回避するためにGmailアドレスから送信する。
これもmailなりsendmailを色々いじればいけるんだろうけど、知らんのでRubyになんとかしてもらう。
これやるためにサーバーにRubyするのは限りなく不毛(他のやり方があるはず)だと思われるので元からRuby入れてる人向け。いちおう1.9でやってます。

まずはメール送信用のgemをインストール。
# gem install mail
あとは以下のスクリプトのUSERNAME、PASSWORDに送信元になるGmailアカウントのユーザー名・パスワードを入れて、username@hoge.comを送信先のアドレスに書き換えて保存。
保存したスクリプトに実行属性付けて /etc/cron.daily/ あたりに(hourlyでもいいけど)入れて寝る。
ちなみにcron.XXXlyは仕様上ドット付きのスクリプトが置けないらしいので、alert.rbみたいな名前じゃなくてalertとかにすること。
メールアカウントのパスワードが生で書かれているファイルをユーザーフォルダ外に置くリスク?知らん。
#!/usr/bin/env ruby
# coding: UTF-8

require 'mail'

def sendMail(result)
 fromUser     = 'USERNAME'
 fromPassword = 'PASSWORD'
 toAddress    = 'username@hoge.com'
 subject      = "「" + `uname -n`.chomp + "」でエラーが発生しました"

 mail = Mail.new
 mail.charset = 'utf-8'
 mail.delivery_method :smtp, { address:   'smtp.gmail.com',
                               port:      587,
                               domain:    'gmail',
                               user_name: fromUser,
                               password:  fromPassword }

 mail.from = fromUser + "@gmail.com"
 mail.to   = toAddress

 mail.subject = subject
 mail.body    = "エラーメッセージは以下の通りです。\n\n" + result

 mail.deliver!
end

result = `zpool status -x`.chomp
if result != "all pools are healthy"
 sendMail(result)
end
あとは障害が発生すると
“「サーバー名」でエラーが発生しました”
みたいなタイトルでこんなメールが届く(多分)。
エラーメッセージは以下の通りです。

  pool: tank
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
   see: http://www.sun.com/msg/ZFS-8000-2Q
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c1t0d0  ONLINE       0     0     0
            c1t1d0  UNAVAIL      0     0     0  cannot open

errors: No known data errors
要は「# zpool status -x」の結果が「all pools are healthy」(=正常)で無い場合に「# zpool status -x」の実行結果を送信しているだけなので、実行コマンドとスクリプトの最後のif文を適当にいじればZFS以外にも転用できるはず。

0 件のコメント:

コメントを投稿