2 # (c) 2008 Thomas Viehmann
3 # Free software licensed under the GPL version 2 or later
6 import os,re,datetime, sys
10 CACHE_FILE = '/srv/ftp.debian.org/misc/dinstall_time_cache'
11 GRAPH_DIR = '/srv/ftp.debian.org/web/stat'
13 LINE = re.compile(r'(?:|.*/)dinstall_(\d{4})\.(\d{2})\.(\d{2})-(\d{2}):(\d{2}):(\d{2})\.log(?:\.bz2)?:'+
14 r'Archive maintenance timestamp \(([^\)]*)\): (\d{2}):(\d{2}):(\d{2})$')
15 UNSAFE = re.compile(r'[^a-zA-Z/\._:0-9\- ]')
17 graphs = {"dinstall1": {"keystolist":["pg_dump1", "i18n 1", "accepted", "make-suite-file-list", "apt-ftparchive",
18 "pdiff", "release files", "w-b", "i18n 2", "apt-ftparchive cleanup"],
20 "dinstall2": {"keystolist":['External Updates', 'p-u-new', 'o-p-u-new', 'cruft', 'import-keyring', 'overrides', 'cleanup', 'scripts', 'mirror hardlinks', 'stats', 'compress', "pkg-file-mapping" ],
22 "totals":{"keystolist":["apt-ftparchive", "apt-ftparchive cleanup"],"showothers":True}}
24 #'mirror hardlinks', 'apt-ftparchive', 'logremove', 'startup', 'import-keyring', 'release files', 'accepted', 'stats', 'o-p-u-new', 'i18n 2', 'locked part finished', 'i18n 1', 'cruft', 'pdiff', 'init', 'cleanup', , 'p-u-new', 'run-parts', 'compress', 'scripts', 'expire_dumps', 'removed', 'make-suite-file-list', 'pg_dump1', 'pg_dump2', 'overrides', 'reports', 'merkel projectb push', 'buildd', 'apt-ftparchive cleanup', 'w-b'
27 for tmp in graphs.values():
28 wantkeys |= set(tmp["keystolist"])
33 if os.path.exists(CACHE_FILE):
34 for l in open(CACHE_FILE):
35 dt, l = l.split('\t',1)
36 l = map(lambda x: (lambda y: (y[0],float(y[1])))(x.split(':',1)), l.split('\t'))
37 newk = [x[0] for x in l if x[0] not in ks]
44 m = UNSAFE.search(' '.join(args))
46 raise Exception("I don't like command line arguments including char '%s'"%m.group(0))
49 for l in os.popen('bzgrep -H "Archive maintenance timestamp" "'+'" "'.join(args)+'"'):
52 raise Exception("woops '%s'"%l)
53 g = map(lambda x: (not x.isdigit() and x) or int(x), m.groups())
54 dt = datetime.datetime(*g[:6])
58 dt2 = datetime.datetime(*(g[:3]+g[-3:]))
59 secs = (dt2-dt).seconds
60 assert secs >= 0 # should add 24*60*60
62 d.setdefault(str(dt),{})[k] = (secs-oldsecs)/60.0
69 print >> sys.stderr, "warning, requested keys not found in any log: "+' '.join(wantkeys-ks)
74 f = open(CACHE_FILE+".tmp","w")
76 print >> f, dk+'\t'+'\t'.join(
77 ["%s:%s"%(k,str(d[dk][k])) for k in kl if k in d[dk]])
79 os.rename(CACHE_FILE+".tmp", CACHE_FILE)
80 datakeys = datakeys[-ITEMS_TO_KEEP:]
82 def dump_file(outfn,keystolist, showothers):
83 showothers = (showothers and 1) or 0
84 # careful, outfn is NOT ESCAPED
85 f = tempfile.NamedTemporaryFile()
86 otherkeys = ks-set(keystolist)
87 print >>f, '\t'.join(keystolist+showothers*['other'])
90 others = sum(map(lambda x: v.get(x,0),otherkeys))
91 print >>f, k+'\t'+'\t'.join(map(lambda x: str(v.get(x,0)), keystolist)+showothers*[str(others)])
95 p = os.popen("R --vanilla --slave > /dev/null","w")
97 d = read.table("%(datafile)s", sep = "\t")
98 #d[["ts"]] <- as.POSIXct(d[["timestamp"]])
99 k = setdiff(names(d),c("ts","timestamp"))
100 #palette(rainbow(max(length(k),2)))
101 palette(c("midnightblue", "gold", "turquoise", "plum4", "palegreen1", "OrangeRed", "green4", "blue",
102 "magenta", "darkgoldenrod3", "tomato4", "violetred2","thistle4", "steelblue2", "springgreen4", "salmon","gray"))
103 #plot(d[["runtime"]],d[["compress"]],type="l",col="blue")
104 #lines(d[["runtime"]],d[["logremove"]],type="l",col="red")
105 #legend(as.POSIXct("2008-12-05"),9500,"logremove",col="red",lty=1)
106 bitmap(file = "%(outfile)s", type="png16m",width=16.9,height=11.8)
107 #plot(d[["ts"]],d[["compress"]],type="l",col="blue")
108 #lines(d[["ts"]],d[["logremove"]],type="l",col="red")
109 barplot(t(d[,k]), col=palette(), xlab="date",ylab="time/minutes"
112 legend(xinch(-1.2),par("usr")[4]+yinch(1),legend=k,
113 ncol=3,fill=1:15) #,xjust=1,yjust=1)
114 text(xinch(10),par("usr")[4]+yinch(.5),"%(title)s", cex=2)
118 """%{'datafile':n,'outfile':outfn,
119 'title':((not showothers)*"partial ")+"dinstall times"})
123 for afn,params in graphs.items():
124 dump_file(os.path.join(GRAPH_DIR,afn+'.png'), **params)