On Mon, 21 Nov 2005, Torsten Schmidt wrote:

> Hi @all,
>
> i made a script, that monitors some web-sites of our company using net::http
> and net::smtp.
>
> it pings multiple sites and it's based on this script:
> http://habtm.com/articles/2005/09/29/website-monitoring-script
>
> every time an error occures, an email ist sent.
> i want to do this every 5 min as a cron-job.
>
> Is there a way to limit the email-notification, that for example only 3
> emails with the same error are delivered?
>
> i would like to prevent my mailbox being filled up, when one site is down
> for the whole night or so
> as it can be done with nagios.
>
> one problem is, that the script has no 'history' information to recognize,
> how many notifications have been sent already.
>
> any suggestion how that can be done?

here's mine - it mails only 3 times.  it's ugly, but functional:

   harp:~ > cat bin/uriup.rb
   #! /home/ahoward/bin/ruby
   #
   # simple script to monitor uris
   #
   # sample cron line
   #
   #   */5 * * * * /usr/local/ruby-1.8.0/bin/ruby /full/path/to/this/script > /dev/null 2>&1
   #

     require "net/http"
     require "net/smtp"
     require "yaml/store"
     require "socket"
   #
   # array of urls to ping
   #
     uris = %w(
       www.codeforpeople.com
       sciruby.codeforpeople.com
       www.zstone.net
       www.ithmezipper.net
     )
   #
   # array of people to notify if urls are down
   #
     recipients = %w(
       ara.t.howard / noaa.gov
     )
   #
   # message format string
   #
     msg_fmt = %Q(
       URI: %s

       TIME: %s

       EXCEPTION: %s\n%s
     )
   #
   # user to send messages as
   #
     user = ENV["USER"] || "ahoward"
   #
   # host to send messages from
   #
     host = ENV["HOSTNAME"] || ENV["HOST"] || Socket::gethostname
   #
   # maximum number of messages to send
   #
     msg_max = 3
   #
   # db class to store codes/notifications
   #
     class DB
       attr "path"
       attr "db"
       def initialize path = File::join(File::expand_path("~"), ".uri.db")
         @path = path
         @db = ::YAML::Store::new @path
       end
       def reset uri
         @db.transaction{ @db[uri] = {"success" => true, "msgs" => 0} }
       end
       def [] uri
         @db.transaction{ @db[uri] } || reset(uri)
       end
       def []= uri, record
         @db.transaction{ @db[uri] = record }
       end
     end
   #
   # umbrella error class
   #
     class SiteDownError < StandardError; end
   #
   # ping each url, mail messages if failure for any reason...
   #
     db = DB::new

     uris.each do |uri|
       begin
         raise SiteDownError unless
           Net::HTTPOK === Net::HTTP::new(uri, 80).get("/")
         y uri => "up"
         db.reset uri

       rescue Exception => e
         y uri => "down"
         record = db[uri]

         if record["msgs"] < msg_max
           now = Time::now
           msg = msg_fmt % [uri, now, e, e.backtrace.join("\n").gsub(%r/^/,"\t")]
           from = "%s@%s" % [user, host]

           Net::SMTP::start("localhost") do |smtp|
             recipients.each do |recipient|
               email = "From: #{ from }\r\n" <<
                       "To: #{ recipient }\r\n" <<
                       "Subject: #{ uri } DOWN @ #{ now }\r\n" <<
                       "\r\n#{ msg }"
               smtp.send_message email, from, recipient
             end
           end

           record["success"] = false
           record["msgs"] += 1
           db[uri] = record
         end
       end
     end


the database files looks like this:

   harp:~ > cat ~/.uri.db
   ---
   www.codeforpeople.com:
     success: true
     msgs: 0
   www.ithmezipper.net:
     msgs: 0
     success: true
   sciruby.codeforpeople.com:
     msgs: 0
     success: true
   www.zstone.net:
     success: true
     msgs: 0

using YAML::Store eliminates the need to roll-your-own.

regards.

-a
-- 
===============================================================================
| ara [dot] t [dot] howard [at] gmail [dot] com
| all happiness comes from the desire for others to be happy.  all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================