This commit is contained in:
parent
f1d5f288f9
commit
31826337dd
@ -7,11 +7,15 @@ Python module to automatically analyze benchmark results
|
|||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
import abc
|
import abc
|
||||||
|
import re
|
||||||
import datetime
|
import datetime
|
||||||
import matplotlib.pyplot as pplot
|
import time
|
||||||
import sentry_sdk
|
|
||||||
|
|
||||||
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:
|
def average(lst: list) -> float:
|
||||||
@ -39,6 +43,8 @@ class Analyzer(abc.ABC):
|
|||||||
|
|
||||||
def __init__(self, typeof='.csv'):
|
def __init__(self, typeof='.csv'):
|
||||||
self.type = typeof
|
self.type = typeof
|
||||||
|
self.responsespersec = []
|
||||||
|
self.latencypersec = []
|
||||||
|
|
||||||
def getfiles(self, directory: str = '.') -> list:
|
def getfiles(self, directory: str = '.') -> list:
|
||||||
"""
|
"""
|
||||||
@ -75,8 +81,6 @@ class CsvAnalyzer(Analyzer):
|
|||||||
Init object
|
Init object
|
||||||
"""
|
"""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.responsespersec = []
|
|
||||||
self.latencypersec = []
|
|
||||||
|
|
||||||
def walkresponsepersec(
|
def walkresponsepersec(
|
||||||
self,
|
self,
|
||||||
@ -97,6 +101,61 @@ class CsvAnalyzer(Analyzer):
|
|||||||
print(average(responsepersec[sec]))
|
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):
|
class HeyAnalyzer(CsvAnalyzer):
|
||||||
"""
|
"""
|
||||||
Analyze hey benchmark output.
|
Analyze hey benchmark output.
|
||||||
@ -130,7 +189,6 @@ class HeyAnalyzer(CsvAnalyzer):
|
|||||||
sec = int(item['offset'].split('.')[0])
|
sec = int(item['offset'].split('.')[0])
|
||||||
if sec not in responsepersec:
|
if sec not in responsepersec:
|
||||||
responsepersec[sec] = []
|
responsepersec[sec] = []
|
||||||
else:
|
|
||||||
responsepersec[sec].append(float(item['response-time']))
|
responsepersec[sec].append(float(item['response-time']))
|
||||||
self.walkresponsepersec(responsepersec, shouldprint)
|
self.walkresponsepersec(responsepersec, shouldprint)
|
||||||
|
|
||||||
@ -168,7 +226,6 @@ class BirbAnalyzer(CsvAnalyzer):
|
|||||||
sec = datetime.datetime.strptime(item['mqtt_arrive_time'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%H:%M:%S")
|
sec = datetime.datetime.strptime(item['mqtt_arrive_time'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%H:%M:%S")
|
||||||
if sec not in responsepersec:
|
if sec not in responsepersec:
|
||||||
responsepersec[sec] = []
|
responsepersec[sec] = []
|
||||||
else:
|
|
||||||
responsepersec[sec].append(float(item['rtt']))
|
responsepersec[sec].append(float(item['rtt']))
|
||||||
self.walkresponsepersec(responsepersec, shouldprint)
|
self.walkresponsepersec(responsepersec, shouldprint)
|
||||||
|
|
||||||
@ -206,7 +263,6 @@ class InputAnalyzer(CsvAnalyzer):
|
|||||||
sec = datetime.datetime.strptime(item['http_start_time'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%H:%M:%S")
|
sec = datetime.datetime.strptime(item['http_start_time'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%H:%M:%S")
|
||||||
if sec not in responsepersec:
|
if sec not in responsepersec:
|
||||||
responsepersec[sec] = []
|
responsepersec[sec] = []
|
||||||
else:
|
|
||||||
firetime = datetime.datetime.strptime(item['http_start_time'], '%Y-%m-%dT%H:%M:%S.%f')
|
firetime = datetime.datetime.strptime(item['http_start_time'], '%Y-%m-%dT%H:%M:%S.%f')
|
||||||
responsearrivetime = datetime.datetime.strptime(item['http_complete_time'],
|
responsearrivetime = datetime.datetime.strptime(item['http_complete_time'],
|
||||||
"%Y-%m-%dT%H:%M:%S.%f")
|
"%Y-%m-%dT%H:%M:%S.%f")
|
||||||
@ -221,7 +277,7 @@ class ChartCreator:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def savetxtplot(csvfile: CsvAnalyzer, directory) -> None:
|
def savetxtplot(csvfile: Analyzer, directory) -> None:
|
||||||
"""
|
"""
|
||||||
Save raw data to txt
|
Save raw data to txt
|
||||||
:param directory:
|
:param directory:
|
||||||
@ -236,7 +292,7 @@ class ChartCreator:
|
|||||||
f.write("%s\n" % item)
|
f.write("%s\n" % item)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def savecsvplot(csvfile: CsvAnalyzer, directory) -> None:
|
def savecsvplot(csvfile: Analyzer, directory) -> None:
|
||||||
"""
|
"""
|
||||||
Save plot of csv file
|
Save plot of csv file
|
||||||
:param csvfile:
|
:param csvfile:
|
||||||
@ -294,6 +350,19 @@ class ChartCreator:
|
|||||||
ChartCreator.savecsvplot(birb, directory)
|
ChartCreator.savecsvplot(birb, directory)
|
||||||
ChartCreator.savetxtplot(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
|
@staticmethod
|
||||||
def analyze_input(abs_directory, directory):
|
def analyze_input(abs_directory, directory):
|
||||||
"""
|
"""
|
||||||
@ -318,10 +387,9 @@ class ChartCreator:
|
|||||||
'SEARCHDIR', default='.') + '/' + directory
|
'SEARCHDIR', default='.') + '/' + directory
|
||||||
print(abs_directory)
|
print(abs_directory)
|
||||||
if 'HEY' in abs_directory.upper():
|
if 'HEY' in abs_directory.upper():
|
||||||
ChartCreator.analyze_hey(abs_directory,directory)
|
ChartCreator.analyze_hey(abs_directory, directory)
|
||||||
else:
|
else:
|
||||||
ChartCreator.analyze_birb(abs_directory,directory)
|
ChartCreator.analyze_ping(abs_directory, directory)
|
||||||
ChartCreator.analyze_input(abs_directory,directory)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
Reference in New Issue
Block a user