Ping 99% Latencies
#!/usr/bin/env python | |
import argparse | |
import datetime | |
import matplotlib as mpl | |
mpl.use('Agg') | |
import matplotlib.pyplot as plt | |
import numpy | |
import os | |
import re | |
import sys | |
import time | |
def total_seconds(td): | |
return td.days*24*60*60 + td.seconds | |
def parse(file): | |
""" | |
Parse through the ping file and get the ping values. | |
:param file: The input file for ping data. | |
:return (x, y): The tuple containing a list of x values which are seconds since start and list y of ping values. | |
""" | |
x = [] | |
y = [] | |
start = None | |
for line in file: | |
# Verify format has a time=#### ms | |
m = re.search("(\d+-\d+-\d+ \d+:\d+:\d+).*time=([0-9\.]+) ms", line) | |
if not m: continue | |
ts = m.group(1) | |
ts = datetime.datetime.strptime(ts, '%Y-%m-%d %H:%M:%S') | |
y_i = float(m.group(2)) | |
if not start: | |
start = ts | |
x_i = 0 | |
else: | |
x_i = total_seconds(ts - start) | |
x.append(x_i) | |
y.append(y_i) | |
return (x, y) | |
def process_99(x, y): | |
""" | |
Group the values in minute buckets and get 99% for each bucket. | |
:param x: The seconds values. | |
:param y: The actual ping values. | |
:return (nx, ny): The tuple containing a list of nx values which are seconds since start and list ny of 99% ping values. | |
""" | |
# Group into minute intervals and calculate 99% | |
nx = [] | |
ny = [] | |
group_x = [] | |
group_y = [] | |
for (x_i, y_i) in zip(x, y): | |
if len(group_x) == 0: | |
group_x.append(x_i) | |
group_y.append(y_i) | |
continue | |
if (x_i - group_x[0]) <= 60: | |
# Within minute interval so group | |
group_x.append(x_i) | |
group_y.append(y_i) | |
else: | |
# Process the past minute and start new | |
x_99 = group_x[0] # Use first data point in minute section as data point | |
y_99 = numpy.percentile(group_y, 99) | |
nx.append(x_99) | |
ny.append(y_99) | |
# Start new group | |
group_x = [x_i] | |
group_y = [y_i] | |
return (nx, ny) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description='Plot 99% ping latencies.') | |
parser.add_argument('-i', '--input', type=str, required=True, help='the ping output file') | |
args = parser.parse_args() | |
input_filename = args.input | |
if not os.path.isfile(input_filename): | |
parser.print_help() | |
sys.exit("Error: File does not exist, please provide a valid file.") | |
# Process the file | |
input_file = open(input_filename, 'r') | |
(x, y) = parse(input_file) | |
input_file.close() | |
(nx, ny) = process_99(x, y) | |
# Plot the data | |
fig = plt.figure() | |
ax = fig.add_subplot(111) | |
ax.set_title("99 Percentile Ping Latencies") | |
ax.set_xlabel("Seconds Since Collection (sec)") | |
ax.set_ylabel("Ping (ms)") | |
ax.plot(nx, ny) | |
fig.savefig(input_filename + ".png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment