source: trunk/essentials/dev-lang/python/Demo/scripts/ftpstats.py

Last change on this file was 3225, checked in by bird, 19 years ago

Python 2.5

File size: 4.5 KB
Line 
1#! /usr/bin/env python
2
3# Extract statistics from ftp daemon log.
4
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.
10
11# The script must be run on the host where the ftp daemon runs.
12# (At CWI this is currently buizerd.)
13
14import os
15import sys
16import re
17import string
18import getopt
19
20pat = '^([a-zA-Z0-9 :]*)!(.*)!(.*)!([<>].*)!([0-9]+)!([0-9]+)$'
21prog = re.compile(pat)
22
23def 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')
104
105def 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)
124
125def show(dict, title, maxitems):
126 if len(dict) > maxitems:
127 title = title + ' (first %d)'%maxitems
128 n = len(title)