isengard-bot/data.py

202 lines
6.1 KiB
Python
Raw Normal View History

2022-02-08 15:46:34 +01:00
import datetime
import logging
from systemd.journal import JournalHandler
# Logging
log = logging.getLogger(__name__)
log.addHandler(JournalHandler())
2022-02-08 20:25:51 +01:00
2023-03-15 19:41:29 +01:00
PRIORITY = {
"OK":0,
"UP":0,
"WARNING":1,
"CRITICAL":2,
"UNKNOWN": 2,
"DOWN": 3,
"DRBD": 3
2023-03-15 19:41:29 +01:00
}
class ProblemData:
"""
Data related to notifications related to a given problem
"""
def __init__(self, name):
self.name = name
self.status = "OK"
self.last_update = datetime.datetime.fromtimestamp(0)
2022-02-08 15:46:34 +01:00
class HostData:
"""
Data related to notifications related to a given host
"""
def __init__(self, name):
self.name = name
2022-02-08 20:25:51 +01:00
self.status = "OK"
2022-02-14 19:13:17 +01:00
self.downtime = False
2023-03-15 19:41:29 +01:00
self.last_update = datetime.datetime.fromtimestamp(0)
self.worst = None
self.problems = set()
2022-02-08 15:46:34 +01:00
2022-02-08 20:25:51 +01:00
2022-02-08 15:46:34 +01:00
class DataStore:
def __init__(self, linkedBot):
log.info("Created DataStore")
2023-03-15 19:41:29 +01:00
self.hosts = set()
2022-02-08 15:46:34 +01:00
self.linkedBot = linkedBot
2023-03-15 19:41:29 +01:00
def notify(self, destmuc):
msg = "```\n"
msg += "*** Isengard - Statut des services ***\n\n"
msg += "-"*80 + "\n"
msg += "| Hôte | Statut | Pire service | Dernière maj |\n"
msg += "-"*80 + "\n"
for host in [x for x in self.hosts]:
msg += "*"
msg += " " + str(host.name)[:22] + " "*(23 - len(str(host.name)[:22])) + "|"
msg += " " + str(host.status)[:8] + " "*(9 - len(str(host.status))) + "|"
msg += " " + str(host.worst)[:16] + " "*(17 - len(str(host.worst)[:16])) + "|"
msg += " " + host.last_update.strftime("%m/%d/%Y, %H:%M:%S")[:21] +\
" "*(22 - len(host.last_update.strftime("%m/%d/%Y, %H:%M:%S"))) +\
"|\n"
msg += "-"*80 + "\n"
if PRIORITY[host.status] == 0:
self.hosts.discard(host)
msg += "```"
# Send notification
log.info("Sending to %s: %s" % (destmuc, msg))
self.linkedBot.push(destmuc, msg)
def get_status(self):
msg = "```\n"
msg += "*** Isengard - Statut des services ***\n\n"
msg += "-"*80 + "\n"
msg += "| Hôte | Statut | Pire service | Dernière maj |\n"
msg += "-"*80 + "\n"
for host in [x for x in self.hosts]:
msg += "*"
msg += " " + str(host.name)[:22] + " "*(23 - len(str(host.name)[:22])) + "|"
msg += " " + str(host.status)[:8] + " "*(9 - len(str(host.status))) + "|"
msg += " " + str(host.worst)[:16] + " "*(17 - len(str(host.worst)[:16])) + "|"
msg += " " + host.last_update.strftime("%m/%d/%Y, %H:%M:%S")[:21] +\
" "*(22 - len(host.last_update.strftime("%m/%d/%Y, %H:%M:%S"))) +\
"|\n"
msg += "-"*80 + "\n"
if PRIORITY[host.status] == 0:
self.hosts.discard(host)
msg += "```"
return msg
2022-02-08 15:46:34 +01:00
def push(self, msg):
2022-02-08 20:25:51 +01:00
"""
Process messages like TYPE|HOST/SERVICE|STATE|OUTPUT|SENDER|COMMENT
"""
2022-02-08 15:46:34 +01:00
# Get current time
2023-03-15 19:41:29 +01:00
curtime = datetime.datetime.now() #.strftime("%m/%d/%Y, %H:%M:%S")
2022-02-08 15:46:34 +01:00
# Get all params
2023-03-15 19:41:29 +01:00
destmuc, mtype, location, status, text, sender, comment = msg.split("|")
mtype = mtype.replace(" ", "")
status = status.replace(" ", "")
2022-02-08 20:25:51 +01:00
# Check if message is about a service or host
try:
2023-03-15 19:41:29 +01:00
hostname, service = location.split("/")
2022-02-08 20:25:51 +01:00
except ValueError:
2023-03-15 19:41:29 +01:00
hostname = location.split("/")[0]
service = None
2022-02-08 20:25:51 +01:00
cur = None
# Look for host
2023-03-15 19:41:29 +01:00
for host in self.hosts:
if host.name == hostname:
cur = host
# Host not found
if not(cur):
cur = HostData(hostname)
self.hosts.add(cur)
log.info("CREATED : %s\n" % cur)
# Retrieve informations and update
log.info("RECEIVED : status %s; mtype %s; location %s; sender %s; comment %s; text %s\n"
% (status, mtype, location, sender, comment, text))
cur.last_update = curtime
# If that's global
if not(service):
# Host is now down
if PRIORITY[status] > PRIORITY[cur.status]:
2022-02-08 20:25:51 +01:00
cur.status = status
2023-03-15 19:41:29 +01:00
cur.worst = "DOWN"
# DOWNTIME
elif "DOWNTIME" in mtype:
2022-02-14 17:41:42 +01:00
pass
2023-03-15 19:41:29 +01:00
# Host is no more down and has no more problems
elif not len(cur.problems):
cur.status = "OK"
cur.worst = None
# Service problem
2022-02-08 15:46:34 +01:00
else:
if "DRBD" in service:
status = "DRBD"
2023-03-15 19:41:29 +01:00
cur_problem = None
# Look for existing problem
for problem in cur.problems:
if problem.name == service:
cur_problem = problem
# Problem not found, create it
if not(cur_problem):
cur_problem = ProblemData(service)
cur.problems.add(cur_problem)
log.info("CREATED PROBLEM in %s : %s\n" % (cur, cur_problem))
cur_problem.last_update = curtime
cur_problem.status = status
if PRIORITY[status] == 0 and cur.worst == cur_problem:
cur.worst = None
cur.status = "OK"
worst_problem = ProblemData(None)
# Find the worst current problem
for problem in cur.problems:
if PRIORITY[problem.status] > PRIORITY[worst_problem.status]:
if problem.last_update > worst_problem.last_update:
worst_problem = problem
if worst_problem.name != None:
cur.status = worst_problem.status
cur.worst = worst_problem.name
if PRIORITY[status] >= 2:
2023-03-15 19:41:29 +01:00
self.notify(destmuc)
return