-
Notifications
You must be signed in to change notification settings - Fork 3
/
wrkparse.py
executable file
·86 lines (72 loc) · 2.74 KB
/
wrkparse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python
import re
import sys
import operator
def text_to_nanos(text):
if text.endswith('ms'):
return float(text.rstrip('ms')) * 1e6
if text.endswith('us'):
return float(text.rstrip('us')) * 1e3
if text.endswith('ns'):
return float(text.rstrip('ns'))
if text.endswith('s'):
return float(text.rstrip('s')) * 1e9
return float(text)
class wrk_output:
pattern = r"""Running (?P<test_duration>.+?) test @ (?P<url>.+)
(?P<nr_threads>\d+) threads and (?P<nr_connections>\d+) connections\s*.*
Thread Stats Avg Stdev Max \+/- Stdev
Latency\s+([^ ]+)\s+([^ ]+)\s+(?P<latency_max>[^ ]+)\s+([^ ]+?)
Req/Sec\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+?)(
Latency Distribution
50%\s*(?P<latency_p50>.*?)
75%\s*(?P<latency_p75>.*?)
90%\s*(?P<latency_p90>.*?)
99%\s*(?P<latency_p99>.*?))?
(?P<total_requests>\d+) requests in (?P<total_duration>.+?), (?P<total_read>.+?) read(
Socket errors: connect (?P<err_connect>\d+), read (?P<err_read>\d+), write (?P<err_write>\d+), timeout (?P<err_timeout>\d+))?(
Non-2xx or 3xx responses: (?P<bad_responses>\d+))?
Requests/sec\:\s*(?P<req_per_sec>.+?)
Transfer/sec\:\s*(?P<transfer>.*?)\s*"""
numeric_attributes = set(['nr_threads', 'req_per_sec', 'total_requests', 'nr_connections'])
def __init__(self, text):
self.m = re.match(self.pattern, text, re.MULTILINE)
if not self.m:
raise Exception('Input does not match')
@property
def requests_per_second(self):
return self.m.group('req_per_sec')
@property
def error_count(self):
return sum(map(int, [
self.m.group('err_timeout') or '0',
self.m.group('err_connect') or '0',
self.m.group('err_write') or '0',
self.m.group('err_read') or '0',
self.m.group('bad_responses') or '0'
]))
@property
def latency_max(self):
return text_to_nanos(self.m.group('latency_max'))
def __getattr__(self, name):
val = self.m.group(name)
if name in self.numeric_attributes:
return float(val)
return val
def print_table(data):
formats = []
for header, value in data:
formats.append('%%%ds' % (max(len(str(value)), len(header))))
format = ' '.join(formats)
print format % tuple(map(operator.itemgetter(0), data))
print format % tuple(map(str, map(operator.itemgetter(1), data)))
def read(filename):
with open(filename) as file:
return wrk_output(file.read())
if __name__ == "__main__":
summary = read(sys.argv[1])
print_table([
('Req/s', summary.requests_per_second),
('Errors', summary.error_count),
('Latency-max [ms]', summary.latency_max / 1e6),
])