Last Updated: 20-August-2015

I wrote the following script in an attempt to monitor my clients-sites uptime, essentially if a sites goes down for whatever reason, I will be notified via email, this doesn't include sites hosted by ourselves (Bronco) as they are monitored already, this is for sites where we only do consulting and they are hosted by others.

The reason I decided to make this was because I happened to be on a reviewing a clients site while it went down (I wasn't doing anything but viewing the source from the browser!), anyway I notified the client and their development team and both were not aware that the site went down so I potentially saved some losses as it was quickly put back online.

The script itself, although it looks simple enough, was admittedly a little tricky; it uses multithreading in order to keep both loops running simultaneously.

The first function email_sender() is what it sounds like, it sends emails, this is powered by gmail, you need to add the email address and password of the account you wish to send the notifications from. You will likely want to authorise the server you are running the script from, start by trying to send an email from it, if it fails go to this link and authorise it, you then need to sent it again within 10 minutes and Google will whitelist it - You'll need to be signed in.

The next function site_up(), runs through the sites you list and checks each one looking for a 200 status response code, if it receives anything else, it passes it on to a temporary dictionary that the second function is watching and deletes it from the main dictionary, after 15 minutes of being sat in the temporary dictionary it checks it again, if it is still returning anything other that a 200 response then it fires an email to the corresponding email address alerting you there is an issue (it's set up like this so you can include colleagues with different email addresses) - Every 15 minutes it checks whether it is back up or not, each time sending an email, once it is back up it fires another email saying the site is once again live - it deletes it from the temporary dictionary and adds the site back into the main pool.

The site_up() function will continue monitoring all the other sites even when a site goes down and into the site_down() monitoring state.


from threading import Thread
import requests ## pip install requests
import time
import smtplib

## email sending function
def email_sender(input_message, email_to, client):
    ''' function to send email '''
    to = email_to
    gmail_user = '' ## email of sender account
    gmail_pwd = '' ## password of sender account
    smtpserver = smtplib.SMTP("smtp.gmail.com",587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(gmail_user, gmail_pwd)
    header = 'To:' + to + '\n' + 'From: ' + gmail_user + '\n' + 'Subject:site down! \n'
    input_message = input_message + client
    msg = header + input_message
    smtpserver.sendmail(gmail_user, to, msg)
    smtpserver.close()

## list of sites to track along with email address to send the alert
clients = {"client":"email",
"client":"email",
"client":"email"}

## temporary dictionary used to do separate monitoring when a site is down
temp_dic = {}

## site 'up' function
def site_up():
    ''' function to monitor up time '''
    while True:
        for client, email in clients.items():
            try:
                r = requests.get(client)
                if r.status_code == 200:
                    print client, 'Site ok'
                    time.sleep(60) ## sleep for 1 min
                else:
                    print client, 'Site first registered as down - added to the "site down" monitoring'
                    temp_dic[client]=email
                    del clients[client]
            except requests.ConnectionError:
                print client, 'Site first registered as down - added to the "site down" monitoring'
                temp_dic[client]=email
                del clients[client]

## site 'down' function
def site_down():
    ''' function to monitor site down time '''
    while True:
        time.sleep(900) ## sleeps 15 mins
        for client, email in temp_dic.items():
        try:
            r = requests.get(client)
            if r.status_code == 200:
                print client, 'Site is back up!!'
                email_sender('Site back up!! ', email, client)
                clients[client]=email
                del temp_dic[client]
            else:
                email_sender('Site down!! ', email, client)
                print client, 'Site Currently down - email sent'
        except requests.ConnectionError:
            email_sender('Site down!! ', email, client)
            print client, 'Site Currently down - email sent'
            
t1 = Thread(target = site_up)
t2 = Thread(target = site_down)
t1.start()
t2.start()

Just an FYI, this is checking the site at a nice slow pace so there will be no concern of flooding the server; making it slow or bringing it down, it also won't register as site traffic within analytics so there is no issues there, it will be viewable within the server logs but just inform the client in the unlikely event that they should question it.

About the author

Image

Craig Addyman @craigaddyman
Head of Digital Marketing. Python Coder.