harry’s memorandum

おれおれメモ

ping.rb

少しだけサーバの死活監視をしたいんだけど、nagiosなどのツールを設定するのも面倒なので、
rubyでicmpって簡単にできるのかな?と検索したところping.rbを発見。標準にあるみたいですね。

require 'ping'
Ping.pingecho "google.com", 10, 80

pingのサーバの死活監視のゴミプログラム。
こんな感じで。下のはgoogle.comを120秒間隔で監視。応答返さない時はfoo@example.comにアラートメール。
監視間隔短すぎると、アラートの嵐のなるのはご愛嬌。

 $ ruby ping_check.rb -h google.com -s  -p 120 -a "foo@example.com"

コード。

#!/usr/bin/env ruby

require 'time'
require 'ping'
require 'net/smtp'
require 'etc'
require 'optparse'

def usage
  puts "#{__FILE__} -h [hostname] -s [smtp server] -p [sec] -a [mailaddress]"
  exit
end

class String
  def is_num?
    begin
      self.integer?
    rescue
      false
    end
  end
end

def sendmail(smtp, from, to, subject, body)
  begin
    Net::SMTP.start( smtp, 25 ) {|smtp|
      smtp.ready( from, to ) {|f|
        f.puts "From: #{from}"
        f.puts "Mime-Version: 1.0"
        f.puts "X-PingCheck-Flg: Yes"
        f.puts "Content-Transfer-Encoding: 7bit"
        f.puts "Content-Type: Text/Plain; charset=iso-2022-jp"
        f.puts "To: #{to}"
        f.puts "Subject: #{subject}"
        f.puts
        f.puts "#{body}"
      }
    }
  rescue
    false
  end
  true
end

# main
opt = OptionParser.new
o = {}
begin
  opt.on('-a value') {|v| o[:a] = v}
  opt.on('-p [value]') {|v| o[:p] = v}
  opt.on('-s value') {|v| o[:s] = v}
  opt.on('-h value') {|v| o[:h] = v}
  opt.parse!(ARGV)
rescue
  puts  "#{__FILE__}: unrecognized option"
  usage
end

usage if o[:a].nil? || o[:s].nil? || o[:h].nil?

default_poll = 60 * 10
to = o[:a]; smtp = o[:s]; host = o[:h]; poll = o[:p].to_i
poll = default_poll if o[:p].nil? || o[:p].is_num? == false
from = "#{Etc.getlogin}@#{Socket.gethostname}"
subject = "** PROBLEM Service Alert: ping - #{host} is WARNING **"
body =<<EOF
#{Time.now}
host down! - #{host}
EOF

while(true) do
  sendmail(smtp,from,to,subject,body) unless Ping.pingecho(host,1)
  sleep poll
end