Index: trunk/udpprofile/web/extractprofile.py |
— | — | @@ -0,0 +1,65 @@ |
| 2 | +#!/usr/bin/python |
| 3 | +# encoding: utf-8 |
| 4 | + |
| 5 | +# showprofile |
| 6 | +# Copyright (c) 2006 Domas Mituzas |
| 7 | + |
| 8 | + |
| 9 | +import sys |
| 10 | +import os |
| 11 | + |
| 12 | +import xml.sax |
| 13 | +from xml.sax import saxutils |
| 14 | +from xml.sax import make_parser |
| 15 | +from xml.sax.handler import feature_namespaces |
| 16 | + |
| 17 | +class ExtractProfile(xml.sax.handler.ContentHandler): |
| 18 | + def __init__(self): |
| 19 | + self.parser=make_parser() |
| 20 | + self.parser.setFeature(feature_namespaces,0) |
| 21 | + self.parser.setContentHandler(self) |
| 22 | + def startElement(self,name,attrs): |
| 23 | + if name=="db": |
| 24 | + self.db=attrs.get("name") |
| 25 | + self.profile[self.db]={} |
| 26 | + if name=="host": |
| 27 | + self.host=attrs.get("name") |
| 28 | + self.profile[self.db][self.host]={} |
| 29 | + if name=="eventname": |
| 30 | + self.inContent=1 |
| 31 | + self.contentData=[] |
| 32 | + if name=="stats": |
| 33 | + self.event["count"]=int(attrs.get("count")) |
| 34 | + if name=="cputime": |
| 35 | + self.event["cpu"]=float(attrs.get("total")) |
| 36 | + self.event["cpusq"]=float(attrs.get("totalsq")) |
| 37 | + if name=="realtime": |
| 38 | + self.event["real"]=float(attrs.get("total")) |
| 39 | + self.event["realsq"]=float(attrs.get("totalsq")) |
| 40 | + |
| 41 | + def endElement(self,name): |
| 42 | + if name=="eventname": |
| 43 | + self.inContent=0 |
| 44 | + self.eventname = "".join(self.contentData) |
| 45 | + self.profile[self.db][self.host][self.eventname]={} |
| 46 | + self.event=self.profile[self.db][self.host][self.eventname] |
| 47 | + if name=="stats": |
| 48 | + self.event["onereal"]=self.event["real"]/self.event["count"] |
| 49 | + self.event["onecpu"]=self.event["cpu"]/self.event["count"] |
| 50 | + def characters(self,chars): |
| 51 | + if self.inContent: |
| 52 | + self.contentData.append(chars) |
| 53 | + |
| 54 | + def getProfile(self): |
| 55 | + return self.profile |
| 56 | + |
| 57 | + def extract(self,file=False): |
| 58 | + if (file==False): |
| 59 | + file=open("profile.xml") |
| 60 | + self.profile={} |
| 61 | + self.inContent=0 |
| 62 | + self.parser.parse(file) |
| 63 | + return self.profile |
| 64 | + |
| 65 | +if __name__ == '__main__': |
| 66 | + print "\nNot a valid entry point" |
Property changes on: trunk/udpprofile/web/extractprofile.py |
___________________________________________________________________ |
Added: svn:keywords |
1 | 67 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 68 | + native |
Added: svn:executable |
3 | 69 | + * |
Index: trunk/udpprofile/web/report.py |
— | — | @@ -0,0 +1,108 @@ |
| 2 | +#!/usr/bin/python |
| 3 | + |
| 4 | +# Configuration and defaults |
| 5 | + |
| 6 | +profilehost = "localhost" |
| 7 | +profileport = 3811 |
| 8 | + |
| 9 | +db="enwiki" |
| 10 | +sort="real" |
| 11 | +limit=50 |
| 12 | + |
| 13 | + |
| 14 | +from extractprofile import ExtractProfile |
| 15 | + |
| 16 | +import cgi |
| 17 | +import cgitb; cgitb.enable() |
| 18 | + |
| 19 | +import socket |
| 20 | + |
| 21 | +print "Content-type: text/html"; |
| 22 | +print "\n" |
| 23 | + |
| 24 | +form=cgi.SvFormContentDict() |
| 25 | + |
| 26 | +if "db" in form: |
| 27 | + db=form["db"] |
| 28 | + |
| 29 | +if "sort" in form: |
| 30 | + sort=form["sort"] |
| 31 | + |
| 32 | +if "limit" in form: limit=int(form["limit"]) |
| 33 | + |
| 34 | +compare="none" |
| 35 | +if "compare" in form: compare=form["compare"] |
| 36 | + |
| 37 | +class SocketSource (socket.socket): |
| 38 | + def read(self,what): |
| 39 | + return self.recv(what,0) |
| 40 | +sock=SocketSource() |
| 41 | +sock.connect((profilehost,profileport)) |
| 42 | + |
| 43 | +cache={} |
| 44 | +fullprofile=ExtractProfile().extract(sock) |
| 45 | +events=fullprofile[db]["-"].items() |
| 46 | +cache[db]=events |
| 47 | +cache["_dbs"]=fullprofile.keys() |
| 48 | +dbs=cache["_dbs"] |
| 49 | + |
| 50 | +total=fullprofile[db]["-"]["-total"] |
| 51 | + |
| 52 | +#cache.close() |
| 53 | +if sort=="name": |
| 54 | + events.sort(lambda x,y: cmp(x[0],y[0])) |
| 55 | +else: |
| 56 | + events.sort(lambda y,x: cmp(x[1][sort],y[1][sort])) |
| 57 | + |
| 58 | +def surl(stype,stext=None,limit=50): |
| 59 | + if(stext==None): stext=stype |
| 60 | + if stype==sort: return """<td>%s</td>"""%stext |
| 61 | + return """<td><a href='report.py?db=%s&sort=%s&limit=%d'>%s</a></td>"""%(db,stype,limit,stext) |
| 62 | + |
| 63 | +print """ |
| 64 | +<style> |
| 65 | +table { width: 100%; } |
| 66 | +td { cell-padding: 1px; |
| 67 | + text-align: right; |
| 68 | + vertical-align: top; |
| 69 | + argin: 2px; |
| 70 | + border: 1px silver dotted; |
| 71 | + background-color: #eeeeee; |
| 72 | +} |
| 73 | +td.name { text-align: left; width: 100%;} |
| 74 | +tr.head td { text-align: center; } |
| 75 | +</style>""" |
| 76 | + |
| 77 | +for dbname in dbs: |
| 78 | + if db == dbname: print " [%s] "%dbname |
| 79 | + else: print " [<a href='report.py?db=%s'>%s</a>] "%(dbname,dbname) |
| 80 | + |
| 81 | +if limit==50: |
| 82 | + print " [ showing %d events, <a href='report.py?db=%s&sort=%s&limit=5000'>show more</a> ] " % (limit,db,sort) |
| 83 | +else: |
| 84 | + print " [ showing %d events, <a href='report.py?db=%s&sort=%s&limit=50'>show less</a> ] " % (limit,db,sort) |
| 85 | + |
| 86 | + |
| 87 | +print """ |
| 88 | +<table> |
| 89 | +<tr class="head">""" |
| 90 | +print surl("name") |
| 91 | +print surl("count") |
| 92 | +print surl("cpu","cpu%") |
| 93 | +print surl("onecpu","cpu/c") |
| 94 | +print surl("real","real%") |
| 95 | +print surl("onereal","real/c") |
| 96 | +print "</tr>" |
| 97 | + |
| 98 | +rowformat="""<tr class="data"><td class="name">%s</td><td>%d</td> |
| 99 | + <td>%.2f</td><td>%.1f</td><td>%.2f</td><td>%.1f</td></tr>""" |
| 100 | + |
| 101 | +for event in events: |
| 102 | + if event[0]=="close": continue |
| 103 | + limit-=1 |
| 104 | + if limit<0: break |
| 105 | + print rowformat % \ |
| 106 | + (event[0].replace(",",", "),event[1]["count"],event[1]["cpu"]/total["cpu"]*100,event[1]["onecpu"]*1000,\ |
| 107 | + event[1]["real"]/total["real"]*100,event[1]["onereal"]*1000) |
| 108 | + |
| 109 | +print "</table>" |
Property changes on: trunk/udpprofile/web/report.py |
___________________________________________________________________ |
Added: svn:keywords |
1 | 110 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 111 | + native |
Added: svn:executable |
3 | 112 | + * |