add ping analyzer
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Torma Kristóf 2021-07-14 11:07:12 +02:00
parent f1d5f288f9
commit 31826337dd
Signed by: tormakris
GPG Key ID: DC83C4F2C41B1047
1 changed files with 88 additions and 20 deletions

View File

@ -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__":