152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project#!/usr/bin/env python 252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## 452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## chewie.py 552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## chews browser http log. draws graph of connections 652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## Be sure there is only one pageload in the log. 752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## 852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## you'll want to 952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## sudo apt-get install python-matplotlib 1052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## before running this 1152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## 1252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 1352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport sys, pylab 1452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 1552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project# can't just use a dict, because there can be dups 1652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectclass Queue: 1752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project def __init__(self): 1852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project self.queue = [] 1952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 2052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project def add(self, url, time): 2152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project self.queue.append([url, time]) 2252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 2352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project def get(self, url): 2452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project for x in range(len(self.queue)): 2552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project rec = self.queue[x] 2652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if rec[0] == url: 2752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project del self.queue[x] 2852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return rec[1] 2952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 3052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project## pull out request lag -- queue to start to done 3152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectdef lag(): 3252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 3352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project font = {'color': '#909090', 'fontsize': 6} 3452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project extractMe = { 3552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'RequestQueue.queueRequest': "Q", 3652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'Connection.openHttpConnection()': "O", 3752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'Request.sendRequest()': "S", 3852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'Request.requestSent()': "T", 3952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'processRequests()': 'R', 4052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'Request.readResponse():': "D", # done 4152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'clearPipe()': 'U', # unqueue 4252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'Request.readResponse()': 'B', # read data block 4352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'Request.readResponseStatus():': 'HR', # read http response line 4452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 'hdr': 'H', # http header 4552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 4652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project keys = extractMe.keys() 4752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project f = open(sys.argv[1], "r") 4952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project t0 = None 5152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # thread, queued, opened, send, sent, reading, read, uri, server, y 5352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # 0 1 2 3 4 5 6 7 8 9 5452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project vals = [] 5552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project queued = Queue() 5752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project opened = {"http0": None, 5852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http1": None, 5952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http2": None, 6052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http3": None, 6152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http4": None, 6252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http5": None} 6352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project active = {"http0": [], 6452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http1": [], 6552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http2": [], 6652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http3": [], 6752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http4": [], 6852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "http5": []} 6952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project connectionCount = 0 7052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project byteCount = 0 7152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project killed = [[], []] 7252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 7352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project while (True): 7452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project line = f.readline() 7552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if len(line) == 0: break 7652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 7752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project splitup = line.split() 7852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 7952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # http only 8052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if splitup[0] != "V/http": continue 8152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project x = splitup[3:] 8352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # filter to named lines 8552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if x[2] not in keys: continue 8652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project x[2] = extractMe[x[2]] 8752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # normalize time 8952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if t0 == None: t0 = int(x[0]) 9052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project x[0] = int(x[0]) - t0 9152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 9252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project thread, action = x[1], x[2] 9352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if action == "Q": 9452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project time, url = x[0], x[3] 9552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project queued.add(url, time) 9652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == "O": 9752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # save opened time and server for this thread, so we can stuff it in l8r 9852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project time, thread, host = x[0], x[1], x[4] 9952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project opened[thread] = [time, host, connectionCount] 10052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project connectionCount += 1 10152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == "S": 10252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project time, thread, url = x[0], x[1], x[3] 10352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project opentime, host, connection = opened[thread] 10452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project qtime = queued.get(url) 10552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record = [thread, qtime, opentime, time, None, None, None, url, host, connection] 10652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project active[thread].append(record) 10752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == "T": 10852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project time, thread = x[0], x[1] 10952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record = active[thread][-1] 11052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record[4] = time 11152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == "R": 11252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project print x 11352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if x[3] in ["sleep", "no", "wait"]: continue 11452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project time, thread, = x[0], x[1] 11552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record = active[thread][0] 11652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record[5] = time 11752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == 'U': 11852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project thread = x[1] 11952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record = active[thread][0] 12052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project killed[0].append(record[9]) 12152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project killed[1].append(x[0]) 12252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project queued.add(record[7], record[1]) 12352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project del active[thread][0] 12452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == "D": 12552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project time, thread = x[0], x[1] 12652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record = active[thread][0] 12752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project record[6] = time 12852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project vals.append(record) 12952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project del active[thread][0] 13052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project print record 13152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # print record[3] / 1000, record[6] / 1000, record[7] 13252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == "B": 13352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project byteCount += int(x[3]) 13452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project elif action == "HR": 13552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project byteCount += int(x[2]) 13652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 13752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project f.close() 13852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 13952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project rng = range(connectionCount) 14052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 14152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project opened = [] 14252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project drawn = [False for x in rng] 14352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project for val in vals: 14452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project y= val[9] 14552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if not drawn[y]: 14652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project drawn[y] = True 14752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project opened.append(val[2]) 14852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project pylab.text(0, y - 0.25, "%s %s %s" % (val[9], val[0][4], val[8]), font) 14952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # define limits 15152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # pylab.plot([vals[-1][6]], rng) 15252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project print opened, rng 15452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project pylab.plot(opened, rng, 'ro') 15552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project pylab.plot(killed[1], killed[0], 'rx') 15652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project for val in vals: 15852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project thread, queued, opened, send, sent, reading, read, uri, server, y = val 15952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # send arrow 16052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project arrow = pylab.Arrow(send, y, sent - send, 0) 16152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project arrow.set_facecolor("g") 16252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project ax = pylab.gca() 16352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project ax.add_patch(arrow) 16452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # read arrow 16552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project arrow = pylab.Arrow(reading, y, read - reading, 0) 16652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project arrow.set_facecolor("r") 16752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project ax = pylab.gca() 16852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project ax.add_patch(arrow) 16952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 17052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project caption = \ 17152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "\nrequests: %s\n" % len(vals) + \ 17252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "byteCount: %s\n" % byteCount + \ 17352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "data rate: %s\n" % (1000 * byteCount / vals[-1][6])+ \ 17452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project "connections: %s\n" % connectionCount 17552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 17652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project pylab.figtext(0.82, 0.30, caption, bbox=dict(facecolor='lightgrey', alpha=0.5)) 17752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 17852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # print lines, [[x, x] for x in range(len(vals))] 17952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project # pylab.plot(lines, [[x, x] for x in range(len(vals))], 'r-') 18052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 18152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project pylab.grid() 18252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project pylab.show() 18352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 18452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectif __name__ == '__main__': lag() 185