[Zodb-checkins] CVS: ZODB3/ZEO - stats.py:1.9

Guido van Rossum guido@python.org
Thu, 5 Sep 2002 17:03:30 -0400


Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv3033

Modified Files:
	stats.py 
Log Message:
Print additional "by-interval" statistics.  By default, the number of
loads and hits and the hit rate is now reported every 15 minutes.


=== ZODB3/ZEO/stats.py 1.8 => 1.9 ===
--- ZODB3/ZEO/stats.py:1.8	Thu Sep  5 13:56:44 2002
+++ ZODB3/ZEO/stats.py	Thu Sep  5 17:03:30 2002
@@ -14,9 +14,11 @@
 ##############################################################################
 """Trace file statistics analyzer.
 
-Usage: stats.py [-v] [-S] tracefile
+Usage: stats.py [-i interval] [-q] [-v] [-S] tracefile
+-i: summarizing interval in minutes (default 15; max 60)
+-q: quiet; don't print sommaries
 -v: verbose; print each record
--S: don't print statistics (implies -v)
+-S: don't print statistics (turns off -q)
 """
 
 """File format:
@@ -58,18 +60,29 @@
 def main():
     # Parse options
     verbose = 0
+    quiet = 0
     dostats = 1
+    interval = 900 # Every 15 minutes
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "vS")
+        opts, args = getopt.getopt(sys.argv[1:], "i:qvS")
     except getopt.error, msg:
         usage(msg)
         return 2
     for o, a in opts:
+        if o == "-i":
+            interval = int(60 * float(a))
+            if interval <= 0:
+                interval = 60
+            elif interval > 3600:
+                interval = 3600
+        if o == "-q":
+            quiet = 1
+            verbose = 0
         if o == "-v":
             verbose = 1
         if o == "-S":
             dostats = 0
-            verbose = 1
+            quiet = 0
     if len(args) != 1:
         usage("exactly one file argument required")
         return 2
@@ -91,6 +104,9 @@
     datarecords = 0
     datasize = 0L
     file0 = file1 = 0
+    byinterval = {}
+    thisinterval = None
+    h0 = he = None
     while 1:
         r = f.read(24)
         if len(r) < 24:
@@ -99,7 +115,16 @@
         ts, code, oid, serial = struct.unpack(">ii8s8s", r)
         if t0 is None:
             t0 = ts
+            thisinterval = t0 / interval
+            h0 = he = ts
         te = ts
+        if ts / interval != thisinterval:
+            if not quiet:
+                dumpbyinterval(byinterval, h0, he)
+            byinterval = {}
+            thisinterval = ts / interval
+            h0 = ts
+        he = ts
         dlen, code = code & 0x7fffff00, code & 0xff
         if dlen:
             datarecords += 1
@@ -115,7 +140,8 @@
             file0 += 1
         code = code & 0x7e
         bycode[code] = bycode.get(code, 0) + 1
-        if verbose or code in (0x00, 0x70):
+        byinterval[code] = byinterval.get(code, 0) + 1
+        if verbose:
             print "%s %d %02x %016x %016x %1s %s" % (
                 time.ctime(ts)[4:-5],
                 current,
@@ -124,9 +150,23 @@
                 U64(serial),
                 version,
                 dlen and str(dlen) or "")
+        if code in (0x00, 0x70):
+            if not quiet:
+                dumpbyinterval(byinterval, h0, he)
+            byinterval = {}
+            thisinterval = ts / interval
+            h0 = he = ts
+            if not quiet:
+                print time.ctime(ts)[4:-5],
+                if code == 0x00:
+                    print '='*20, "Restart", '='*20
+                else:
+                    print '-'*20, "Flip->%d" % current, '-'*20
     bytes = f.tell()
     f.close()
     rte = time.time()
+    if not quiet:
+        dumpbyinterval(byinterval, h0, he)
 
     # Error if nothing was read
     if not records:
@@ -158,6 +198,25 @@
                 addcommas(bycode.get(code, 0)),
                 code,
                 explain.get(code) or "*** unknown code ***")
+
+def dumpbyinterval(byinterval, h0, he):
+    loads = 0
+    hits = 0
+    for code in byinterval.keys():
+        if code & 0x70 == 0x20:
+            n = byinterval[code]
+            loads += n
+            if code in (0x2A, 0x2C, 0x2E):
+                hits += n
+    if not loads:
+        return
+    if loads:
+        hr = 100.0 * hits / loads
+    else:
+        hr = 0.0
+    print "%s-%s %10s loads, %10s hits,%5.1f%% hit rate" % (
+        time.ctime(h0)[4:-8], time.ctime(he)[14:-8],
+        addcommas(loads), addcommas(hits), hr)
 
 def hitrate(bycode):
     loads = 0