mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Plugins 0.1 - Basic definition
This commit is contained in:
316
front/plugins/website_monitoring/script.py
Executable file
316
front/plugins/website_monitoring/script.py
Executable file
@@ -0,0 +1,316 @@
|
||||
#!/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
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
import sqlite3
|
||||
import pwd
|
||||
import os
|
||||
|
||||
con = sqlite3.connect("monitoring.db")
|
||||
cur = con.cursor()
|
||||
|
||||
#DELAY = 60 # Delay between site queries
|
||||
EMAIL_INTERVAL = 1800 # Delay between alert emails
|
||||
|
||||
last_email_time = {} # Monitored sites and timestamp of last alert sent
|
||||
|
||||
# Message template for alert
|
||||
MESSAGE = """From: {sender}
|
||||
To: {receivers}
|
||||
Subject: Monitor Service Notification
|
||||
|
||||
You are being notified that {site} is experiencing a {status} status!
|
||||
"""
|
||||
|
||||
# Workflow
|
||||
|
||||
def main():
|
||||
global cur
|
||||
global con
|
||||
|
||||
prepare_service_monitoring_env()
|
||||
service_monitoring()
|
||||
print_service_monitoring_changes()
|
||||
# prepare_service_monitoring_notification()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def prepare_service_monitoring_env ():
|
||||
global con
|
||||
global cur
|
||||
|
||||
sql_create_table = """ CREATE TABLE IF NOT EXISTS Services_Events(
|
||||
moneve_URL TEXT NOT NULL,
|
||||
moneve_DateTime TEXT NOT NULL,
|
||||
moneve_StatusCode NUMERIC NOT NULL,
|
||||
moneve_Latency TEXT NOT NULL
|
||||
); """
|
||||
cur.execute(sql_create_table)
|
||||
|
||||
sql_create_table = """ CREATE TABLE IF NOT EXISTS Services_CurrentScan(
|
||||
cur_URL TEXT NOT NULL,
|
||||
cur_DateTime TEXT NOT NULL,
|
||||
cur_StatusCode NUMERIC NOT NULL,
|
||||
cur_Latency TEXT NOT NULL,
|
||||
cur_AlertEvents INTEGER DEFAULT 0,
|
||||
cur_AlertDown INTEGER DEFAULT 0,
|
||||
cur_StatusChanged INTEGER DEFAULT 0,
|
||||
cur_LatencyChanged INTEGER DEFAULT 0
|
||||
); """
|
||||
cur.execute(sql_create_table)
|
||||
|
||||
sql_create_table = """ CREATE TABLE IF NOT EXISTS Services(
|
||||
mon_URL TEXT NOT NULL,
|
||||
mon_MAC TEXT,
|
||||
mon_LastStatus NUMERIC NOT NULL,
|
||||
mon_LastLatency TEXT NOT NULL,
|
||||
mon_LastScan TEXT NOT NULL,
|
||||
mon_Tags TEXT,
|
||||
mon_AlertEvents INTEGER DEFAULT 0,
|
||||
mon_AlertDown INTEGER DEFAULT 0,
|
||||
PRIMARY KEY(mon_URL)
|
||||
); """
|
||||
cur.execute(sql_create_table)
|
||||
|
||||
# Update Service with lastLatence, lastScan and lastStatus
|
||||
# -----------------------------------------------------------------------------
|
||||
def set_service_update(_mon_URL, _mon_lastScan, _mon_lastStatus, _mon_lastLatence,):
|
||||
global con
|
||||
global cur
|
||||
|
||||
sqlite_insert = """UPDATE Services SET mon_LastScan=?, mon_LastStatus=?, mon_LastLatency=? WHERE mon_URL=?;"""
|
||||
|
||||
table_data = (_mon_lastScan, _mon_lastStatus, _mon_lastLatence, _mon_URL)
|
||||
cur.execute(sqlite_insert, table_data)
|
||||
con.commit()
|
||||
|
||||
# Insert Services_Events with moneve_URL, moneve_DateTime, moneve_StatusCode and moneve_Latency
|
||||
# -----------------------------------------------------------------------------
|
||||
def set_services_events(_moneve_URL, _moneve_DateTime, _moneve_StatusCode, _moneve_Latency):
|
||||
global con
|
||||
global cur
|
||||
|
||||
sqlite_insert = """INSERT INTO Services_Events
|
||||
(moneve_URL, moneve_DateTime, moneve_StatusCode, moneve_Latency)
|
||||
VALUES (?, ?, ?, ?);"""
|
||||
|
||||
table_data = (_moneve_URL, _moneve_DateTime, _moneve_StatusCode, _moneve_Latency)
|
||||
cur.execute(sqlite_insert, table_data)
|
||||
con.commit()
|
||||
|
||||
# Insert Services_Events with moneve_URL, moneve_DateTime, moneve_StatusCode and moneve_Latency
|
||||
# -----------------------------------------------------------------------------
|
||||
def set_services_current_scan(_cur_URL, _cur_DateTime, _cur_StatusCode, _cur_Latency):
|
||||
global con
|
||||
global cur
|
||||
|
||||
cur.execute("SELECT * FROM Services WHERE mon_URL = ?", [_cur_URL])
|
||||
rows = cur.fetchall()
|
||||
for row in rows:
|
||||
_mon_AlertEvents = row[6]
|
||||
_mon_AlertDown = row[7]
|
||||
_mon_StatusCode = row[2]
|
||||
_mon_Latency = row[3]
|
||||
|
||||
if _mon_StatusCode != _cur_StatusCode:
|
||||
_cur_StatusChanged = 1
|
||||
else:
|
||||
_cur_StatusChanged = 0
|
||||
|
||||
if _mon_Latency == "99999" and _mon_Latency != _cur_Latency:
|
||||
_cur_LatencyChanged = 1
|
||||
elif _cur_Latency == "99999" and _mon_Latency != _cur_Latency:
|
||||
_cur_LatencyChanged = 1
|
||||
else:
|
||||
_cur_LatencyChanged = 0
|
||||
|
||||
sqlite_insert = """INSERT INTO Services_CurrentScan
|
||||
(cur_URL, cur_DateTime, cur_StatusCode, cur_Latency, cur_AlertEvents, cur_AlertDown, cur_StatusChanged, cur_LatencyChanged)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?);"""
|
||||
|
||||
table_data = (_cur_URL, _cur_DateTime, _cur_StatusCode, _cur_Latency, _mon_AlertEvents, _mon_AlertDown, _cur_StatusChanged, _cur_LatencyChanged)
|
||||
cur.execute(sqlite_insert, table_data)
|
||||
con.commit()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def service_monitoring_log(site, status, latency):
|
||||
# global monitor_logfile
|
||||
|
||||
# Log status message to log file
|
||||
with open('monitor.log', 'a') as monitor_logfile:
|
||||
monitor_logfile.write("{} | {} | {} | {}\n".format(strftime("%Y-%m-%d %H:%M:%S"),
|
||||
site,
|
||||
status,
|
||||
latency,
|
||||
)
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
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("Successfully sent email")
|
||||
except smtplib.SMTPException:
|
||||
print("Error sending email ({}:{})".format(host, port))
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def check_services_health(site):
|
||||
# Enable self signed SSL
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
"""Send GET request to input site and return status code"""
|
||||
try:
|
||||
resp = requests.get(site, verify=False, timeout=10)
|
||||
latency = resp.elapsed
|
||||
latency_str = str(latency)
|
||||
latency_str_seconds = latency_str.split(":")
|
||||
format_latency_str = latency_str_seconds[2]
|
||||
if format_latency_str[0] == "0" and format_latency_str[1] != "." :
|
||||
format_latency_str = format_latency_str[1:]
|
||||
return resp.status_code, format_latency_str
|
||||
except requests.exceptions.SSLError:
|
||||
pass
|
||||
except:
|
||||
latency = "99999"
|
||||
return 503, latency
|
||||
|
||||
# ----------------------------------------------------------------------------- Duplicat
|
||||
def get_username():
|
||||
|
||||
return pwd.getpwuid(os.getuid())[0]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_services_list():
|
||||
global cur
|
||||
global con
|
||||
|
||||
with open('monitor.log', 'a') as monitor_logfile:
|
||||
monitor_logfile.write("... Get Services List\n")
|
||||
monitor_logfile.close()
|
||||
|
||||
cur.execute("SELECT mon_URL FROM Services")
|
||||
rows = cur.fetchall()
|
||||
|
||||
sites = []
|
||||
for row in rows:
|
||||
sites.append(row[0])
|
||||
|
||||
return sites
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def flush_services_current_scan():
|
||||
global cur
|
||||
global con
|
||||
|
||||
with open('monitor.log', 'a') as monitor_logfile:
|
||||
monitor_logfile.write("... Flush previous scan results\n")
|
||||
monitor_logfile.close()
|
||||
|
||||
cur.execute("DELETE FROM Services_CurrentScan")
|
||||
con.commit()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def print_service_monitoring_changes():
|
||||
global cur
|
||||
global con
|
||||
|
||||
print("Services Monitoring Changes")
|
||||
changedStatusCode = cur.execute("SELECT COUNT() FROM Services_CurrentScan WHERE cur_StatusChanged = 1").fetchone()[0]
|
||||
print("... Changed StatusCodes: ", str(changedStatusCode))
|
||||
changedLatency = cur.execute("SELECT COUNT() FROM Services_CurrentScan WHERE cur_LatencyChanged = 1").fetchone()[0]
|
||||
print("... Changed Reachability: ", str(changedLatency))
|
||||
with open('monitor.log', 'a') as monitor_logfile:
|
||||
monitor_logfile.write("\nServices Monitoring Changes:\n")
|
||||
monitor_logfile.write("... Changed StatusCodes: " + str(changedStatusCode))
|
||||
monitor_logfile.write("\n... Changed Reachability: " + str(changedLatency))
|
||||
monitor_logfile.write("\n")
|
||||
monitor_logfile.close()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# def prepare_service_monitoring_notification():
|
||||
# global cur
|
||||
# global con
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def service_monitoring():
|
||||
global cur
|
||||
global con
|
||||
|
||||
# Empty Log and write new header
|
||||
print("Prepare Services Monitoring")
|
||||
print("... Prepare Logfile")
|
||||
with open('monitor.log', 'w') as monitor_logfile:
|
||||
monitor_logfile.write("Pi.Alert [Prototype]:\n---------------------------------------------------------\n")
|
||||
monitor_logfile.write("Current User: %s \n\n" % get_username())
|
||||
monitor_logfile.write("Monitor Web-Services\n")
|
||||
monitor_logfile.write("Timestamp: " + strftime("%Y-%m-%d %H:%M:%S") + "\n")
|
||||
monitor_logfile.close()
|
||||
|
||||
print("... Get Services List")
|
||||
sites = get_services_list()
|
||||
|
||||
print("... Flush previous scan results")
|
||||
flush_services_current_scan()
|
||||
|
||||
print("Start Services Monitoring")
|
||||
with open('monitor.log', 'a') as monitor_logfile:
|
||||
monitor_logfile.write("\nStart Services Monitoring\n\n| Timestamp | URL | StatusCode | ResponseTime |\n-----------------------------------------------\n")
|
||||
monitor_logfile.close()
|
||||
|
||||
for site in sites:
|
||||
last_email_time[site] = 0 # Initialize timestamp as 0
|
||||
|
||||
while sites:
|
||||
for site in sites:
|
||||
status,latency = check_services_health(site)
|
||||
scantime = strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# Debugging
|
||||
# print("{} - {} STATUS: {} ResponseTime: {}".format(strftime("%Y-%m-%d %H:%M:%S"),
|
||||
# site,
|
||||
# status,
|
||||
# latency)
|
||||
# )
|
||||
|
||||
# Write Logfile
|
||||
service_monitoring_log(site, status, latency)
|
||||
# Insert Services_Events with moneve_URL, moneve_DateTime, moneve_StatusCode and moneve_Latency
|
||||
set_services_events(site, scantime, status, latency)
|
||||
# Insert Services_CurrentScan with moneve_URL, moneve_DateTime, moneve_StatusCode and moneve_Latency
|
||||
set_services_current_scan(site, scantime, status, latency)
|
||||
|
||||
sys.stdout.flush()
|
||||
|
||||
# Update Service with lastLatence, lastScan and lastStatus after compare with services_current_scan
|
||||
set_service_update(site, scantime, status, latency)
|
||||
|
||||
break
|
||||
|
||||
else:
|
||||
with open('monitor.log', 'a') as monitor_logfile:
|
||||
monitor_logfile.write("\n\nNo site(s) to monitor!")
|
||||
monitor_logfile.close()
|
||||
|
||||
#===============================================================================
|
||||
# BEGIN
|
||||
#===============================================================================
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
Reference in New Issue
Block a user