auto import from //depot/cupcake/@135843
diff --git a/tools/axl/chewie.py b/tools/axl/chewie.py
new file mode 100755
index 0000000..7ed2ba6
--- /dev/null
+++ b/tools/axl/chewie.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+##
+## chewie.py
+## chews browser http log. draws graph of connections
+## Be sure there is only one pageload in the log.
+##
+## you'll want to
+## sudo apt-get install python-matplotlib
+## before running this
+##
+
+import sys, pylab
+
+# can't just use a dict, because there can be dups
+class Queue:
+ def __init__(self):
+ self.queue = []
+
+ def add(self, url, time):
+ self.queue.append([url, time])
+
+ def get(self, url):
+ for x in range(len(self.queue)):
+ rec = self.queue[x]
+ if rec[0] == url:
+ del self.queue[x]
+ return rec[1]
+
+## pull out request lag -- queue to start to done
+def lag():
+
+ font = {'color': '#909090', 'fontsize': 6}
+ extractMe = {
+ 'RequestQueue.queueRequest': "Q",
+ 'Connection.openHttpConnection()': "O",
+ 'Request.sendRequest()': "S",
+ 'Request.requestSent()': "T",
+ 'processRequests()': 'R',
+ 'Request.readResponse():': "D", # done
+ 'clearPipe()': 'U', # unqueue
+ 'Request.readResponse()': 'B', # read data block
+ 'Request.readResponseStatus():': 'HR', # read http response line
+ 'hdr': 'H', # http header
+ }
+ keys = extractMe.keys()
+
+ f = open(sys.argv[1], "r")
+
+ t0 = None
+
+ # thread, queued, opened, send, sent, reading, read, uri, server, y
+ # 0 1 2 3 4 5 6 7 8 9
+ vals = []
+
+ queued = Queue()
+ opened = {"http0": None,
+ "http1": None,
+ "http2": None,
+ "http3": None,
+ "http4": None,
+ "http5": None}
+ active = {"http0": [],
+ "http1": [],
+ "http2": [],
+ "http3": [],
+ "http4": [],
+ "http5": []}
+ connectionCount = 0
+ byteCount = 0
+ killed = [[], []]
+
+ while (True):
+ line = f.readline()
+ if len(line) == 0: break
+
+ splitup = line.split()
+
+ # http only
+ if splitup[0] != "V/http": continue
+
+ x = splitup[3:]
+
+ # filter to named lines
+ if x[2] not in keys: continue
+ x[2] = extractMe[x[2]]
+
+ # normalize time
+ if t0 == None: t0 = int(x[0])
+ x[0] = int(x[0]) - t0
+
+ thread, action = x[1], x[2]
+ if action == "Q":
+ time, url = x[0], x[3]
+ queued.add(url, time)
+ elif action == "O":
+ # save opened time and server for this thread, so we can stuff it in l8r
+ time, thread, host = x[0], x[1], x[4]
+ opened[thread] = [time, host, connectionCount]
+ connectionCount += 1
+ elif action == "S":
+ time, thread, url = x[0], x[1], x[3]
+ opentime, host, connection = opened[thread]
+ qtime = queued.get(url)
+ record = [thread, qtime, opentime, time, None, None, None, url, host, connection]
+ active[thread].append(record)
+ elif action == "T":
+ time, thread = x[0], x[1]
+ record = active[thread][-1]
+ record[4] = time
+ elif action == "R":
+ print x
+ if x[3] in ["sleep", "no", "wait"]: continue
+ time, thread, = x[0], x[1]
+ record = active[thread][0]
+ record[5] = time
+ elif action == 'U':
+ thread = x[1]
+ record = active[thread][0]
+ killed[0].append(record[9])
+ killed[1].append(x[0])
+ queued.add(record[7], record[1])
+ del active[thread][0]
+ elif action == "D":
+ time, thread = x[0], x[1]
+ record = active[thread][0]
+ record[6] = time
+ vals.append(record)
+ del active[thread][0]
+ print record
+ # print record[3] / 1000, record[6] / 1000, record[7]
+ elif action == "B":
+ byteCount += int(x[3])
+ elif action == "HR":
+ byteCount += int(x[2])
+
+ f.close()
+
+ rng = range(connectionCount)
+
+ opened = []
+ drawn = [False for x in rng]
+ for val in vals:
+ y= val[9]
+ if not drawn[y]:
+ drawn[y] = True
+ opened.append(val[2])
+ pylab.text(0, y - 0.25, "%s %s %s" % (val[9], val[0][4], val[8]), font)
+
+ # define limits
+ # pylab.plot([vals[-1][6]], rng)
+
+ print opened, rng
+ pylab.plot(opened, rng, 'ro')
+ pylab.plot(killed[1], killed[0], 'rx')
+
+ for val in vals:
+ thread, queued, opened, send, sent, reading, read, uri, server, y = val
+ # send arrow
+ arrow = pylab.Arrow(send, y, sent - send, 0)
+ arrow.set_facecolor("g")
+ ax = pylab.gca()
+ ax.add_patch(arrow)
+ # read arrow
+ arrow = pylab.Arrow(reading, y, read - reading, 0)
+ arrow.set_facecolor("r")
+ ax = pylab.gca()
+ ax.add_patch(arrow)
+
+ caption = \
+ "\nrequests: %s\n" % len(vals) + \
+ "byteCount: %s\n" % byteCount + \
+ "data rate: %s\n" % (1000 * byteCount / vals[-1][6])+ \
+ "connections: %s\n" % connectionCount
+
+ pylab.figtext(0.82, 0.30, caption, bbox=dict(facecolor='lightgrey', alpha=0.5))
+
+ # print lines, [[x, x] for x in range(len(vals))]
+ # pylab.plot(lines, [[x, x] for x in range(len(vals))], 'r-')
+
+ pylab.grid()
+ pylab.show()
+
+if __name__ == '__main__': lag()