source: indico/bin/utils/zodb/transactions_stats.py @ 55dc34

burotelhello-world-walkthroughipv6new-webexv0.97-seriesv0.98-seriesv0.98.2v0.98.3v0.98b1v0.98b2v0.99v1.0v1.1
Last change on this file since 55dc34 was 78dc7d, checked in by Jose Benito <jose.benito.gonzalez@…>, 3 years ago

[ADD] ZODB scripts reviewed

  • added .sh script
  • Property mode set to 100644
File size: 6.6 KB
Line 
1# -*- coding: utf-8 -*-
2##
3##
4## This file is part of CDS Indico.
5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 CERN.
6##
7## CDS Indico is free software; you can redistribute it and/or
8## modify it under the terms of the GNU General Public License as
9## published by the Free Software Foundation; either version 2 of the
10## License, or (at your option) any later version.
11##
12## CDS Indico is distributed in the hope that it will be useful, but
13## WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15## General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20
21import os
22import sys
23import struct
24import time
25import ZODB.FileStorage
26import datetime
27from ZODB.utils import U64, get_pickle_metadata
28from persistent.TimeStamp import TimeStamp
29from ZODB.tests.StorageTestBase import zodb_unpickle
30from optparse import OptionParser
31from time import gmtime, strftime
32from datetime import timedelta
33
34StringType = str
35
36class Stat(object):
37    def __init__(self):
38        self.mean = []
39        self.n = 0
40        self.records = 0
41
42def GetInHMS(seconds, showSec):
43    hours = int(seconds / 3600)
44    seconds -= 3600*hours
45    minutes = int(seconds / 60.0)
46    seconds -= 60*minutes
47    if hours == 0:
48        if(showSec): return "%02dmin %02dsecs" % (minutes, seconds)
49        else: return "%02dmin" % (minutes)
50
51    if(showSec): return "%02dh %02dmin %02dsecs" % (hours, minutes, seconds)
52    else: return "%02dh %02dmin" % (hours, minutes)
53
54def pretty_size( size ):
55    if size < 1024:
56        return "%sB"%(size)
57    kb = size / 1024.0
58    if kb < 1024.0:
59        return '%0.1fKb'%kb
60    else:
61        mb = kb/1024.0
62        return '%0.1fMb'%mb
63
64def U64(s):
65    return struct.unpack(">Q", s)[0]
66
67def oid_repr(oid):
68    if isinstance(oid, StringType) and len(oid) == 8:
69        return '%16x' % U64(oid)
70    else:
71        return repr(oid)
72
73def main():
74    usage = "usage: %prog [options] filename"
75    parser = OptionParser(usage=usage)
76    parser.add_option("-n", "--number", dest="num",
77                  help="display only the 'n' busiest days", default=20, type="int")
78    parser.add_option("-f", "--file", dest="filename", action="store", type="string",
79                  help="your FileStorage")
80    parser.add_option("-d", "--date", dest="date", action="store", type="string",
81                  help="show the stats only for the date d (format dd-mm-yyyy)")
82    parser.add_option("-a", "--days", dest="days", action="store", default="0", type="string",
83                  help="show the stats only for the last 'a' days")
84
85    (options, args) = parser.parse_args()
86    objectsToDisplay = options.num
87
88    if options.filename:
89        fname = options.filename
90    else:
91        print "You have to enter the filename, see --help for details"
92        return 2
93
94    stats = {}
95    start = time.time()
96    size = os.stat(fname).st_size
97    it = ZODB.FileStorage.FileIterator(fname)
98
99    lastPercent = 0.0
100    recordsCounter = 0
101    interval = 0.005
102    dataFound = False
103    now = datetime.date.today()
104
105    try:
106        for t in it:
107
108            #Format the date of the current transaction following dd-mm-yyyy
109            ts = TimeStamp(t.tid)
110            then = datetime.date(int(ts.year()), int(ts.month()), int(ts.day()))
111            delta = timedelta(days=int(options.days))
112
113            if((not int(options.days)) or (now - then < delta)):
114                dateT = strftime("%d-%m-%Y", [int(ts.year()), int(ts.month()), int(ts.day()),0,0,0,0,0,0] )
115                percent = float(it._file.tell())/float(size) * 100
116                #Check if we found the searched date
117                if options.date:
118                    if str(dateT) == str(options.date):
119                        dataFound = True
120                    elif dataFound:
121                        break
122
123                #Show the percentage of the work completed and the remaining time
124                if(percent - lastPercent > interval):
125                    spentTime = time.time() - start
126                    remainingTime = spentTime / float(it._file.tell()) * (float(size)) - spentTime
127                    sys.stderr.write("\r%f%% complete, time spent %s,  remaining time: %s, recordsCounter %d" % (percent,GetInHMS(time.time() - start, True),  GetInHMS(remainingTime, False), recordsCounter))
128
129                    lastPercent = percent
130
131                stat = stats.get(dateT)
132                if stat is None:
133                    stat = stats[dateT] = Stat()
134                    stat.n = 1
135                else:
136                    stat.n += 1
137
138                for r in t:
139                    #need to reduce the time of the dictionary stats from time to time
140                    if recordsCounter % (objectsToDisplay*100) == 0:
141                        tmp = {}
142                        for date, s in sorted(
143                            stats.items(), key=lambda (k,v): v.n, reverse=True)[0: objectsToDisplay]:
144                            tmp[date] = s
145                        try:
146                            tmp[dateT] = stats[dateT]
147                        except KeyError:
148                            pass
149
150                        stats = tmp
151
152                    if r.data:
153                        mod, klass = get_pickle_metadata(r.data)
154                        l = len(r.data)
155                        stat = stats.get(dateT)
156                        stat.records += 1
157                    recordsCounter += 1
158
159                stat = stats.get(dateT)
160                if stat is not None:
161                    stat.mean.append(TimeStamp(t.tid).timeTime())
162
163    except KeyboardInterrupt:
164        pass
165
166    print "\n"
167    print "%-15s %17s %17s %22s" % ("Date", "Transactions","Records Changed", "Average interval")
168    print "%s" % "_" * 74
169
170    if options.date:
171        for date, s in sorted(
172            stats.items(), key=lambda (k,v): v.n, reverse=True):
173            meanTime = 0
174            for i in range(1,len(s.mean)):
175                meanTime += s.mean[i] - s.mean[i-1]
176            if str(date) == str(options.date):
177                print "%-15s | %15d | %15d | %15f secs" % (date, (s.n),s.records, meanTime/s.n)
178    else:
179        for date, s in sorted(
180            stats.items(), key=lambda (k,v): v.n, reverse=True)[0: objectsToDisplay]:
181            meanTime = 0
182            for i in range(1,len(s.mean)):
183                meanTime += s.mean[i] - s.mean[i-1]
184
185            print "%-15s | %15d | %15d | %15f secs" % (date, (s.n), s.records, meanTime/s.n)
186
187
188if __name__ == '__main__':
189    main()
190
Note: See TracBrowser for help on using the repository browser.