From af78b994ff41acdae65ff0b5907bbd0e6debe9c4 Mon Sep 17 00:00:00 2001 From: Jannik Schönartz Date: Tue, 20 Nov 2018 16:25:07 +0100 Subject: Initial Commmit --- bwLpStatus.py | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 bwLpStatus.py (limited to 'bwLpStatus.py') diff --git a/bwLpStatus.py b/bwLpStatus.py new file mode 100644 index 0000000..a0642a8 --- /dev/null +++ b/bwLpStatus.py @@ -0,0 +1,212 @@ +import subprocess +import urllib.request +import urllib.error +#import mysql.connector +import thriftpy +from thriftpy.rpc import make_client +from thriftpy.transport import TFramedTransportFactory +import shutil +import datetime +import os + +# Global variables +statusList = [] +logEntries = [] +newLogIndex = 0 + +# Class of the status objects +class Status: + def __init__(self, name, host, state, status, service, msg = '', data = []): + # Name of the service. + self.name = name + + # Hostname (Domain, ip, ...) + self.host = host + + # State of the response. (success, warning, error) <-- This class is responsible for the coloring (green, orange, red) + self.state = state + + # Status of the check. (Online, Offline, Temporaily not available, Some services unavailable, ...) <-- This text is shown on the website + self.status = status + + # Type of the service. (ping, https, http, mysql, ...) + self.service = service + + # Message e.g. error message + self.msg = msg + + # Data the request return e.g. organisation list from the thrift client. + self.data = data + +class LogEntry: + def __init__(self, date, host, service, state, msg = '', data = []): + self.date = date + self.host = host + self.service = service + self.state = state + self.msg = msg + self.data = data + +class Organisation: + def __init__(self, id, name): + self.id = id + self.name = name + + def __repr__(self): + return str(self.__dict__) + +# Check connection functions. +def ping(name, hostname): + # Ping a hostname and tell if the server is up or down. + print('Ping request ... ', end='') + response = subprocess.Popen( + ['ping', '-c', '1', hostname], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + response = response.communicate() + output = response[0].decode('utf-8') + error = response[1].decode('utf-8') + + # Error happend + if error != '': + print('error: ', end='') + print(error) + statusList.append(Status(name, hostname, 'error', 'Offline', 'ping', error.rstrip())) + else: + print('success') + statusList.append(Status(name, hostname, 'success', 'Online', 'ping')) + + logStatus(statusList[-1]) + +def https(name, url): + print('HTTPS request') + try: + r = urllib.request.urlopen(url) + if r.getcode() == 200: + statusList.append(Status(name, url, 'success', 'Online', 'https')) + else: + statusList.append(Status(name, url, 'error', 'Offline', 'https')) + + except urllib.error.URLError as e: + statusList.append(Status(name, url, 'error', 'Offline', 'https')) + + logStatus(statusList[-1]) + +def mysql(self, host, user, passwd, db): + print('MYSQL request start ...') + #db = mysql.connector.connect( + # host='localhost', + # user='openslx', + # passwd='geheim', + # database='openslx' + #) + #cursor = db.cursor() + #cursor.execute('SELECT * FROM user') + #result = cursor.fetchall() + #for user in result: + # print(user[1]) + +def thrift(name, ip, port): + print('THRIFT request start ...') + bwlp_thrift = thriftpy.load('bwlp.thrift', module_name='bwlp_thrift') + # masterserver = make_client(bwlp_thrift.MasterServer, '132.230.4.16', 9090, trans_factory=TFramedTransportFactory()) + # TODO: TRY CATCH + satserver = make_client(bwlp_thrift.SatelliteServer, ip, port, trans_factory=TFramedTransportFactory()) + organisations = satserver.getAllOrganizations() + organisationList = [] + for org in organisations: + organisationList.append(Organisation(org.organizationId, org.displayName)) + + host = ip + ':' + str(port) + statusList.append(Status(name, host, 'success', 'Online (' + str(len(organisationList)) + ')', 'thrift', data=organisationList)) + logStatus(statusList[-1]) + +# Parses the log from the logfile. Fills the logEntries array. +def parseLog(): + if not (os.path.exists('bwLpStatusLog.txt')): + return + with open('bwLpStatusLog.txt', 'r') as log: + for line in log: + line = line.strip() + entry = line.split('\t') + if len(entry) < 4: continue + logEntries.append(LogEntry(entry[0], entry[1], entry[2], entry[3], '' if len(entry) < 5 else entry[4], [] if len(entry) < 6 else entry[5])) + global newLogIndex + newLogIndex = len(logEntries) + +# Writes updated log in the logfile. +def writeLog(): + with open('bwLpStatusLog.txt', 'a') as log: + for entry in logEntries[newLogIndex:]: + log_string = entry.date + '\t' + entry.service + '\t' + entry.state + '\t' + entry.host + if entry.msg != '': log_string += '\t' + entry.msg + if entry.data != []: log_string += '\t' + str(entry.data) + log.write(log_string + '\n') + +# Returns the most recent log object to a given status. None if there is none. +def getLogEntry(status): + # for entry in reversed(logEntries): + # if status.host == entry.host and status.service == entry.service: return entry + return next((x for x in reversed(logEntries) if (x.host == status.host) and (x.service == status.service)), None) + +# Checks weather the status has to be logged or not. (Does the status has changes from the last time?) +def logStatus(status): + obj = getLogEntry(status) + if (obj is None) or (status.state != obj.state): + date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + logEntries.append(LogEntry(date, status.host, status.service, status.state, status.msg, status.data)) + +# Parse the logfile. +parseLog() + +# Call the checks. +https('Masterserver HTTPS Service', 'https://bwlp-masterserver.ruf.uni-freiburg.de') +ping('Masterserver IP Ping', '132.230.4.16') +ping('Fileserver Ping', 'files.bwlp.ks.uni-freiburg.de') +ping('Backup fileserver Ping', 'bwlp-backup.ruf.uni-freiburg.de') +thrift('Thrift SAT', '132.230.8.192', 9090) +ping('BAS Ping', 'bas.intra.uni-freiburg.de') +ping('yc', '127.0.0.2') +ping('yx', '127.0.0.3') + +# Write the new logfile. +writeLog() + +# HTML Processing to generate the website. +code = '\r\n' +for status in statusList: + # Prepare and calculate the time since the server is online / offline + obj = getLogEntry(status) + now = datetime.datetime.now() + date = datetime.datetime.strptime(obj.date, '%Y-%m-%d %H:%M:%S') + time = now - date + days = time.days + hours = time.seconds // 3600 + minutes = (time.seconds // 60) % 60 + timeString = '' + if days > 0: + timeString += str(days) + ' days ' + if hours > 0: + timeString += str(hours) + ' hours ' + if minutes > 0: + timeString += str(minutes) + ' minutes' + + code += '
' + status.name + '
' + status.host + '
' + status.status + '
' + timeString + '
\r\n' + +# Generate the html code for the log. +log = '\r\n' +for entry in reversed(logEntries): + log += '
[' + entry.date + ']
[' + entry.service + ']
[' + entry.state + ']
[' + entry.host +']
' + entry.msg + '
' + +# Copy the .html file and replace the %CONTENT% to generate the final html file. +shutil.copyfile('bwlpMonitor_template.html', 'bwlpMonitor.html') + +# Replace the %CONTENT% in the template with the actual html code. +html = open('bwlpMonitor_template.html') +html2 = open('bwlpMonitor.html', 'w') +for line in html: + html2.write(line.replace('%CONTENT%', code).replace('%LOG%', log)) + +html.close() +html2.close() -- cgit v1.2.3-55-g7522