import repository from arizona
[raven.git] / lib / ravenlib / stats.py
1 #! /usr/bin/env python
2
3 """ Raven Statistic Counter Module
4
5     Usage:
6         # increment the counter "foo" by 1
7         ravenlib.stats.update("foo", 1)
8
9         # generate owl script output for the counters "foo" and "bar" under the
10         # module name "mymodule"
11         ravenlib.stats.print_owl("mymodule", ["foo","bar"])
12 """
13
14 import os
15 import sys
16 import tempfile
17 import time
18 import traceback
19
20 STATS_DIR = "/var/raven/statistics"
21
22 initialized = False
23
24 def init():
25     global initialized
26     if initialized:
27         return
28
29     if not os.path.exists(STATS_DIR):
30         os.makedirs(STATS_DIR)
31
32     initialized = True
33
34 def filename_from_date():
35     ltime = time.localtime()
36     return str(ltime.tm_year) + "-" + str(ltime.tm_mon) + "-" + str(ltime.tm_mday)
37
38 def read(fn):
39     f = open(fn, "rt")
40     dict = eval(f.read())
41     return dict
42
43 def write(fn, dict):
44     (f, tmpfn) = tempfile.mkstemp(dir = os.path.dirname(fn))
45     os.write(f,str(dict))
46     os.close(f)
47
48     # let the file be readable/writeable by anyone so root and user processes
49     # can both use the stats module.
50     os.chmod(tmpfn, 0666)
51
52     os.rename(tmpfn, fn)
53
54     # XXX: delete tmpfn if it still exists
55
56 def update_file(fn, name, amount):
57     fn = os.path.join(STATS_DIR, fn)
58     if os.path.exists(fn):
59         dict = read(fn)
60     else:
61         dict = {}
62
63     item = dict.get(name, {"sum": 0, "date": 0.0, "count": 0, "last": 0})
64
65     item["sum"] = item.get("sum",0) + amount
66     item["date"] = time.time()
67     item["last"] = amount
68     item["count"] = item.get("count",0) + 1
69
70     dict[name] = item
71
72     write(fn, dict)
73
74 def update(name, amount=1):
75     try:
76         init()
77         update_file(filename_from_date(), name, amount)
78         update_file("total", name, amount)
79     except:
80         # don't want the statistics module causing any faults in otherwise
81         # correctly-running code, so catch all exceptions, dump them to
82         # stderr, and continue as if nothing went wrong
83         print >> sys.stderr, traceback.format_exc()
84
85 def print_owl(module=None, sumKeyList=None, avgKeyList=None, countKeyList=None):
86     """
87         sumKeyList = a list of keys that should be printed as sums
88         avgKeyList = a list of keys that should be printed as averages
89         countKeyList = a list of keys that should be printed as counts
90     """
91     init()
92
93     fn = os.path.join(STATS_DIR, filename_from_date())
94     if not os.path.exists(fn):
95         return
96
97     dict = read(fn)
98
99     if module:
100         print "[" + module + "]"
101
102     for key in dict.keys():
103         if (avgKeyList != None) and (key in avgKeyList):
104             item = dict[key]
105             sum = item.get("sum",0)
106             count = item.get("count",0)
107             if count > 0:
108                 print key + "_avg=" + str(sum/count)
109             else:
110                 print key + "_avg=" + str(0)
111
112         if (countKeyList != None) and (key in countKeyList):
113             item = dict[key]
114             count = item.get("count",0)
115             print key+"_cnt=" + str(count)
116
117         if (sumKeyList==None) or (key in sumKeyList):
118             item = dict[key]
119             print key + "=" + str(item.get("sum",0))
120
121 def print_list():
122     init()
123
124     fn = os.path.join(STATS_DIR, filename_from_date())
125     if not os.path.exists(fn):
126         return
127
128     dict = read(fn)
129
130     for key in dict.keys():
131         print key
132
133 def print_summary(keys):
134     init()
135
136     fn = os.path.join(STATS_DIR, filename_from_date())
137     if not os.path.exists(fn):
138         return
139
140     dict = read(fn)
141
142     for key in keys:
143         item = dict.get(key, {})
144         sum = item.get("sum",0)
145         count = item.get("count",0)
146         last = item.get("last",0)
147         date = item.get("date",0)
148
149         if (count >0):
150             avg = sum/count
151         else:
152             avg = 0
153
154         print " name:", key
155         print "  sum:", sum
156         print "count:", count
157         print "  avg:", avg
158         print " last:", last
159         print " date:", time.ctime(date)
160
161
162 def main():
163     if len(sys.argv) < 2:
164         print "syntax: stats.py [update|sum|avg|count] <name>"
165         print "                 list"
166         return
167
168     if sys.argv[1] == "update":
169         update(sys.argv[2], 1)
170     elif sys.argv[1] == "sum":
171         print_owl(None, [sys.argv[2]])
172     elif sys.argv[1] == "avg":
173         print_owl(None, [], [sys.argv[2]])
174     elif sys.argv[1] == "count":
175         print_owl(None, [], [], [sys.argv[2]])
176     elif sys.argv[1] == "show":
177         print_summary([sys.argv[2]])
178     elif sys.argv[1] == "list":
179         print_list()
180
181 if __name__=="__main__":
182    main()
183
184
185
186