Added section about configuring logging in a library. Thanks to Thomas Heller for...
[python.git] / Demo / scripts / ftpstats.py
blob5c1599e6639fa11bb9bbdfd70623587da5acdc4a
1 #! /usr/bin/env python
3 # Extract statistics from ftp daemon log.
5 # Usage:
6 # ftpstats [-m maxitems] [-s search] [file]
7 # -m maxitems: restrict number of items in "top-N" lists, default 25.
8 # -s string: restrict statistics to lines containing this string.
9 # Default file is /usr/adm/ftpd; a "-" means read standard input.
11 # The script must be run on the host where the ftp daemon runs.
12 # (At CWI this is currently buizerd.)
14 import os
15 import sys
16 import re
17 import string
18 import getopt
20 pat = '^([a-zA-Z0-9 :]*)!(.*)!(.*)!([<>].*)!([0-9]+)!([0-9]+)$'
21 prog = re.compile(pat)
23 def main():
24 maxitems = 25
25 search = None
26 try:
27 opts, args = getopt.getopt(sys.argv[1:], 'm:s:')
28 except getopt.error, msg:
29 print msg
30 print 'usage: ftpstats [-m maxitems] [file]'
31 sys.exit(2)
32 for o, a in opts:
33 if o == '-m':
34 maxitems = string.atoi(a)
35 if o == '-s':
36 search = a
37 file = '/usr/adm/ftpd'
38 if args: file = args[0]
39 if file == '-':
40 f = sys.stdin
41 else:
42 try:
43 f = open(file, 'r')
44 except IOError, msg:
45 print file, ':', msg
46 sys.exit(1)
47 bydate = {}
48 bytime = {}
49 byfile = {}
50 bydir = {}
51 byhost = {}
52 byuser = {}
53 bytype = {}
54 lineno = 0
55 try:
56 while 1:
57 line = f.readline()
58 if not line: break
59 lineno = lineno + 1
60 if search and string.find(line, search) < 0:
61 continue
62 if prog.match(line) < 0:
63 print 'Bad line', lineno, ':', repr(line)
64 continue
65 items = prog.group(1, 2, 3, 4, 5, 6)
66 (logtime, loguser, loghost, logfile, logbytes,
67 logxxx2) = items
68 ## print logtime
69 ## print '-->', loguser
70 ## print '--> -->', loghost
71 ## print '--> --> -->', logfile
72 ## print '--> --> --> -->', logbytes
73 ## print '--> --> --> --> -->', logxxx2
74 ## for i in logtime, loghost, logbytes, logxxx2:
75 ## if '!' in i: print '???', i
76 add(bydate, logtime[-4:] + ' ' + logtime[:6], items)
77 add(bytime, logtime[7:9] + ':00-59', items)
78 direction, logfile = logfile[0], logfile[1:]
79 # The real path probably starts at the last //...
80 while 1:
81 i = string.find(logfile, '//')
82 if i < 0: break
83 logfile = logfile[i+1:]
84 add(byfile, logfile + ' ' + direction, items)
85 logdir = os.path.dirname(logfile)
86 ## logdir = os.path.normpath(logdir) + '/.'
87 while 1:
88 add(bydir, logdir + ' ' + direction, items)
89 dirhead = os.path.dirname(logdir)
90 if dirhead == logdir: break
91 logdir = dirhead
92 add(byhost, loghost, items)
93 add(byuser, loguser, items)
94 add(bytype, direction, items)
95 except KeyboardInterrupt:
96 print 'Interrupted at line', lineno
97 show(bytype, 'by transfer direction', maxitems)
98 show(bydir, 'by directory', maxitems)
99 show(byfile, 'by file', maxitems)
100 show(byhost, 'by host', maxitems)
101 show(byuser, 'by user', maxitems)
102 showbar(bydate, 'by date')
103 showbar(bytime, 'by time of day')
105 def showbar(dict, title):
106 n = len(title)
107 print '='*((70-n)/2), title, '='*((71-n)/2)
108 list = []
109 keys = dict.keys()
110 keys.sort()
111 for key in keys:
112 n = len(str(key))
113 list.append((len(dict[key]), key))
114 maxkeylength = 0
115 maxcount = 0
116 for count, key in list:
117 maxkeylength = max(maxkeylength, len(key))
118 maxcount = max(maxcount, count)
119 maxbarlength = 72 - maxkeylength - 7
120 for count, key in list:
121 barlength = int(round(maxbarlength*float(count)/maxcount))
122 bar = '*'*barlength
123 print '%5d %-*s %s' % (count, maxkeylength, key, bar)
125 def show(dict, title, maxitems):
126 if len(dict) > maxitems:
127 title = title + ' (first %d)'%maxitems
128 n = len(title)
129 print '='*((70-n)/2), title, '='*((71-n)/2)
130 list = []
131 keys = dict.keys()
132 for key in keys:
133 list.append((-len(dict[key]), key))
134 list.sort()
135 for count, key in list[:maxitems]:
136 print '%5d %s' % (-count, key)
138 def add(dict, key, item):
139 if dict.has_key(key):
140 dict[key].append(item)
141 else:
142 dict[key] = [item]
144 if __name__ == "__main__":
145 main()