-
Notifications
You must be signed in to change notification settings - Fork 10
/
monitor.py
129 lines (103 loc) · 4.15 KB
/
monitor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env python
from __future__ import unicode_literals
from time import sleep, time, strftime
import requests
import io
import smtplib
import sys
from smtp_config import sender, password, receivers, host, port
DELAY = 60 # Delay between site queries
EMAIL_INTERVAL = 1800 # Delay between alert emails
last_email_time = {} # Monitored sites and timestamp of last alert sent
# Define escape sequences for colored terminal output
COLOR_DICT = {
"green": "\033[92m",
"red": "\033[91m",
"yellow": "\033[93m",
"bold": "\033[1m",
"end": "\033[0m",
}
# Message template for alert
MESSAGE = """From: {sender}
To: {receivers}
Subject: Monitor Service Notification
You are being notified that {site} is experiencing a {status} status!
"""
def colorize(text, color):
"""Return input text wrapped in ANSI color codes for input color."""
return COLOR_DICT[color] + str(text) + COLOR_DICT['end']
def error_log(site, status):
"""Log errors to stdout and log file, and send alert email via SMTP."""
# Print colored status message to terminal
print "\n({}) {} STATUS: {}".format(strftime("%a %b %d %Y %H:%M:%S"),
site,
colorize(status, "yellow"),
)
# Log status message to log file
with open('monitor.log', 'a') as log:
log.write("({}) {} STATUS: {}\n".format(strftime("%a %b %d %Y %H:%M:%S"),
site,
status,
)
)
def send_alert(site, status):
"""If more than EMAIL_INTERVAL seconds since last email, resend email"""
if (time() - last_email_time[site]) > EMAIL_INTERVAL:
try:
smtpObj = smtplib.SMTP(host, port) # Set up SMTP object
smtpObj.starttls()
smtpObj.login(sender, password)
smtpObj.sendmail(sender,
receivers,
MESSAGE.format(sender=sender,
receivers=", ".join(receivers),
site=site,
status=status
)
)
last_email_time[site] = time() # Update time of last email
print colorize("Successfully sent email", "green")
except smtplib.SMTPException:
print colorize("Error sending email ({}:{})".format(host, port), "red")
def ping(site):
"""Send GET request to input site and return status code"""
resp = requests.get(site)
return resp.status_code
def get_sites():
"""Return list of unique URLs from input and sites.txt file."""
sites = sys.argv[1:] # Accept sites from command line input
# Read in additional sites to monitor from sites.txt file
try:
sites += [site.strip() for site in io.open('sites.txt', mode='r').readlines()]
except IOError:
print colorize("No sites.txt file found", "red")
# Add protocol if missing in URL
for site in range(len(sites)):
if sites[site][:7] != "http://" and sites[site][:8] != "https://":
sites[site] = "http://" + sites[site]
# Eliminate exact duplicates in sites
sites = list(set(sites))
return sites
def main():
sites = get_sites()
for site in sites:
print colorize("Beginning monitoring of {}".format(site), "bold")
last_email_time[site] = 0 # Initialize timestamp as 0
while sites:
try:
for site in sites:
status = ping(site)
if status == 200:
print "\b" + colorize(".", "green"),
sys.stdout.flush()
else:
error_log(site, status)
send_alert(site, status)
sleep(DELAY)
except KeyboardInterrupt:
print colorize("\n-- Monitoring canceled --", "red")
break
else:
print colorize("No site(s) input to monitor!", "red")
if __name__ == '__main__':
main()