############################################################################### # # Siteminder.py # # by Mark Gregory Turansky (markturansky@gmail.com) # on September 14, 2005 # # This program monitors websites for availability, alerting administrators # when the site is offline or returns error values. # # A siteminder server page (such as siteminder.aspx) is required on the server # being monitored. As a server page, it can test anything the developer # wants. A server-side check for database availability is a good idea, for # example, or checking the status of jobs being run. # # The return value of a siteminder page must be "OK" (case-insensitive) in # plain text. Any other text is considered an error and will be send to # the alert recipients list. If, for example, a connection to the database # could not be established or a job failed, the siteminder page author can # include a meaningful message in the page. This text becomes useful to site # administrators. # # Site data is stored in a "sites.json" file that should be located in the same # directory as this siteminder program. Site data is stored using object # notation, like this: # # { # "localhost":{ # "url":"http://localhost/siteminder.jsp", # "alert": [ # "someone@somewhere.com" # ] # }, # # "anotherHost":{ # "url":"https://somehwere/siteminder.aspx", # "alert": [ # "someone@somewhere.com", "theAdmin@keymind.com" # ] # } # } # # In terms of object notation, each site is an object with two properties: # # url: the url for siteminder to monitor # alert: a list of addresses to send email to when the test fails. # # See http://www.JSON.org for more information about object notation. # # This siteminder software comes without warranty of any kind. It is licensed # under the Douglas Crockford's JSON License, because I like the # "Used for Good, not Evil" clause: # # http://www.json.org/license.html # ############################################################################### import urllib, smtplib # # the email message sent to alert recipients, as a multiline string. # %s is a placeholder for values inserted at runtime. # # the first line is an SMTP header. It requires two blank lines between it # and the body of the email (see the SMTP protocol if you want more info). # msg = """Subject: Siteminder alert! %s failed. The URL %s failed Siteminder's test. The expected value is "OK" or "ok" but the value returned was: %s """ # # test a site, alerting admins when a value other than "OK" is returned. # def test(site, sitename): try: url = urllib.urlopen(site["url"]) text = url.readlines() token = text[0].strip().lower() if not token == "ok": print sitename + " failed." alert(site, sitename, text); else: print sitename + " ok." except: alert(site, sitename, "Error connecting to site.") # # test all sites # def runtests(sites): for sitename in sites: test(sites[sitename], sitename) # # read the JSON data file and return it as an object (via the eval function). # def getSiteData(): src = open("sites.json").read() return eval(src) # # send email to the alert recipients list # def alert(site, sitename, txt): for email in site["alert"]: print " alerting " + email smtp.sendmail( "siteminder@yourdomain.com", #FROM address email, #TO address msg % (sitename, site["url"], "".join(txt)) #EMAIL BODY ) # # run the program # def main(username, pwd): smtp.login(username, pwd); runtests(getSiteData()) smtp.quit() # # setup the mail server # smtp = smtplib.SMTP("mail.server.com") # # run it! # main("username", "password")