diff --git a/make_graphs.py b/make_graphs.py index 150d582..61585c0 100644 --- a/make_graphs.py +++ b/make_graphs.py @@ -7,11 +7,15 @@ Python module to automatically analyze benchmark results import csv import os import abc +import re import datetime -import matplotlib.pyplot as pplot -import sentry_sdk +import time -sentry_sdk.init("https://c1a84042595b448b94681750523dcc34@sentry.kmlabz.com/20") +import matplotlib.pyplot as pplot + +EPOCHRE = re.compile(r"\[[0-9]+\.[0-9]+]") +TIMERE = re.compile(r"time=[0-9]+\.[0-9]+ ms") +NUMBERRE = re.compile(r"[0-9]+\.[0-9]+") def average(lst: list) -> float: @@ -39,6 +43,8 @@ class Analyzer(abc.ABC): def __init__(self, typeof='.csv'): self.type = typeof + self.responsespersec = [] + self.latencypersec = [] def getfiles(self, directory: str = '.') -> list: """ @@ -75,8 +81,6 @@ class CsvAnalyzer(Analyzer): Init object """ super().__init__() - self.responsespersec = [] - self.latencypersec = [] def walkresponsepersec( self, @@ -97,6 +101,61 @@ class CsvAnalyzer(Analyzer): print(average(responsepersec[sec])) +class PingAnalyzer(Analyzer): + """ + Analyze ping command output. + """ + + def __init__(self): + """ + Init object + """ + super().__init__(typeof='.pingtxt') + + def walkresponsepersec( + self, + responsepersec: dict, + shouldprint: bool) -> None: + """ + Walks through reponsepersec dict + :param responsepersec: + :param shouldprint: + :return: + """ + for sec in responsepersec: + if len(responsepersec[sec]) != 0: + self.responsespersec.append(len(responsepersec[sec])) + self.latencypersec.append(average(responsepersec[sec])) + if shouldprint: + print(len(responsepersec[sec])) + print(average(responsepersec[sec])) + + def processfile( + self, + fname, + shouldprint: bool = False): + """ + Process a single file. + :param fname: + :param shouldprint: + :return: + """ + with open(fname, 'r') as f: + lines = f.readlines() + responsepersec = {} + for line in lines: + try: + epoch = float(NUMBERRE.findall(EPOCHRE.findall(line)[0])[0]) + epoch_time = time.strftime("%H:%M:%S", time.localtime(epoch)) + delay = float(NUMBERRE.findall(TIMERE.findall(line)[0])[0]) + if epoch_time not in responsepersec: + responsepersec[epoch_time] = [] + responsepersec[epoch_time].append(delay) + except Exception as e: + print(f"line skipped because {e}") + self.walkresponsepersec(responsepersec, shouldprint) + + class HeyAnalyzer(CsvAnalyzer): """ Analyze hey benchmark output. @@ -130,8 +189,7 @@ class HeyAnalyzer(CsvAnalyzer): sec = int(item['offset'].split('.')[0]) if sec not in responsepersec: responsepersec[sec] = [] - else: - responsepersec[sec].append(float(item['response-time'])) + responsepersec[sec].append(float(item['response-time'])) self.walkresponsepersec(responsepersec, shouldprint) @@ -168,8 +226,7 @@ class BirbAnalyzer(CsvAnalyzer): sec = datetime.datetime.strptime(item['mqtt_arrive_time'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%H:%M:%S") if sec not in responsepersec: responsepersec[sec] = [] - else: - responsepersec[sec].append(float(item['rtt'])) + responsepersec[sec].append(float(item['rtt'])) self.walkresponsepersec(responsepersec, shouldprint) @@ -206,12 +263,11 @@ class InputAnalyzer(CsvAnalyzer): sec = datetime.datetime.strptime(item['http_start_time'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%H:%M:%S") if sec not in responsepersec: responsepersec[sec] = [] - else: - firetime = datetime.datetime.strptime(item['http_start_time'], '%Y-%m-%dT%H:%M:%S.%f') - responsearrivetime = datetime.datetime.strptime(item['http_complete_time'], - "%Y-%m-%dT%H:%M:%S.%f") - latency = responsearrivetime - firetime - responsepersec[sec].append(int(latency.total_seconds() * 1000)) + firetime = datetime.datetime.strptime(item['http_start_time'], '%Y-%m-%dT%H:%M:%S.%f') + responsearrivetime = datetime.datetime.strptime(item['http_complete_time'], + "%Y-%m-%dT%H:%M:%S.%f") + latency = responsearrivetime - firetime + responsepersec[sec].append(int(latency.total_seconds() * 1000)) self.walkresponsepersec(responsepersec, shouldprint) @@ -221,7 +277,7 @@ class ChartCreator: """ @staticmethod - def savetxtplot(csvfile: CsvAnalyzer, directory) -> None: + def savetxtplot(csvfile: Analyzer, directory) -> None: """ Save raw data to txt :param directory: @@ -236,7 +292,7 @@ class ChartCreator: f.write("%s\n" % item) @staticmethod - def savecsvplot(csvfile: CsvAnalyzer, directory) -> None: + def savecsvplot(csvfile: Analyzer, directory) -> None: """ Save plot of csv file :param csvfile: @@ -294,6 +350,19 @@ class ChartCreator: ChartCreator.savecsvplot(birb, directory) ChartCreator.savetxtplot(birb, directory) + @staticmethod + def analyze_ping(abs_directory, directory): + """ + Analyze ping command output + :param abs_directory: + :param directory: + :return: + """ + ping = PingAnalyzer() + ping.processallfiles(abs_directory) + ChartCreator.savecsvplot(ping, directory) + ChartCreator.savetxtplot(ping, directory) + @staticmethod def analyze_input(abs_directory, directory): """ @@ -318,10 +387,9 @@ class ChartCreator: 'SEARCHDIR', default='.') + '/' + directory print(abs_directory) if 'HEY' in abs_directory.upper(): - ChartCreator.analyze_hey(abs_directory,directory) + ChartCreator.analyze_hey(abs_directory, directory) else: - ChartCreator.analyze_birb(abs_directory,directory) - ChartCreator.analyze_input(abs_directory,directory) + ChartCreator.analyze_ping(abs_directory, directory) if __name__ == "__main__":