Skip to content

Instantly share code, notes, and snippets.

@davisp
Created May 3, 2019 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davisp/310e9d2569daec9d706043ca7b1c6a3e to your computer and use it in GitHub Desktop.
Save davisp/310e9d2569daec9d706043ca7b1c6a3e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import datetime as dt
import os
import sys
import xml.dom.minidom
import fdb.tuple
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import matplotlib.ticker as ticker
IGNORE_TYPES = (
"TransactionTrace_Commit_ReadConflictRange",
"TransactionTrace_Commit_WriteConflictRange",
"TransactionTrace_Commit_Mutation"
)
ROW_SPACING = 0.5
COLORS = {
"GetVersion": "tab:purple",
"Get": "tab:orange",
"GetRange": "tab:red",
"Commit": "tab:green"
}
def unpack(v):
try:
v = v.decode('string_escape')
except:
pass
for i in range(min(8, len(v))):
try:
return fdb.tuple.unpack(v[i:])
except Exception as e:
pass
return v.encode('string_escape')
def load_trace_file(filename):
dom = xml.dom.minidom.parse(filename)
begins = {}
events = []
for ev in dom.getElementsByTagName('Event'):
ev = dict((k.lower(), v) for (k, v) in ev.attributes.items())
ev['time'] = float(ev['time'])
if ev['type'] in IGNORE_TYPES:
continue
if ev['type'].startswith('TransactionTrace_'):
ev['type'] = ev['type'][len('TransactionTrace_'):]
if 'latency' in ev:
ev['latency'] = float(ev['latency'])
if 'latency' in ev:
events.append(ev)
tzero = min((ev['time'] - ev['latency']) for ev in events)
for ev in events:
ev['time'] = ev['time'] - tzero
return events
def create_gantt_chart(events):
fig = plt.figure(figsize = (20, 70))
ax = fig.add_subplot(111)
for i, ev in enumerate(events):
if 'latency' in ev:
left = ev['time'] - ev['latency']
width = ev['latency']
else:
left = ev['time']
width = 0.01
ypos = (i * ROW_SPACING) + ROW_SPACING
ax.barh(
ypos,
width,
left = left,
height = 0.30,
align = 'center',
color = COLORS[ev['type']],
alpha = 0.8
)
if ev['type'] == 'Commit':
nmuts = ev['nummutations']
size = ev['commitsizebytes']
label = "Ops: %s Bytes: %s" % (nmuts, size)
ax.text(
left + 0.001,
ypos,
label,
verticalalignment = 'center',
fontsize = 8
)
ytick_pos = []
ytick_labels = []
for i, ev in enumerate(events):
ytick_pos.append((i * ROW_SPACING) + ROW_SPACING)
ytick_labels.append(ev['type'])
ytick_pos, ytick_labels = plt.yticks(ytick_pos, ytick_labels)
plt.setp(ytick_labels, fontsize = 13)
ax.set_ylim(bottom = -0.1, top = (1 + len(events)) * ROW_SPACING)
ax.grid(color = 'gray', linestyle = '-', alpha = 0.2)
ax.grid(which = 'minor', axis = 'x', color = 'gray', linestyle = '-', alpha = 0.2)
xticks = [0.0]
xtick = 0.0
while xtick < events[-1]['time']:
xtick += 0.005
xticks.append(xtick)
plt.xticks(xticks)
ax.xaxis.set_minor_locator(ticker.AutoMinorLocator())
xtick_labels = ax.get_xticklabels()
plt.setp(xtick_labels, rotation = 30, fontsize = 14)
font = font_manager.FontProperties(size='small')
ax.legend(loc = 1, prop = font)
ax.invert_yaxis()
plt.savefig('gantt.png')
os.system("open gantt.png")
def main():
if len(sys.argv) != 2:
print("usage: %s trace.xml" % sys.argv[0])
exit(1)
events = load_trace_file(sys.argv[1])
create_gantt_chart(events)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment