Mercurial > cpython-lru_cache-weakref
annotate Demo/scripts/ftpstats.py @ 5817:48b94de85bf3 legacy-trunk
Extensive changes by AMK.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Thu, 17 Jul 1997 16:29:42 +0000 |
| parents | 73758db2f464 |
| children | b52864c5e9c9 |
| rev | line source |
|---|---|
|
4573
73758db2f464
/usr/local/bin/python -> /usr/bin/env python
Guido van Rossum <guido@python.org>
parents:
1501
diff
changeset
|
1 #! /usr/bin/env python |
| 1501 | 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 stdandard input. | |
| 10 | |
| 11 # The script must be run on the host where the ftp daemon runs. | |
| 12 # (At CWI this is currently buizerd.) | |
| 13 | |
| 14 import os | |
| 15 import sys | |
| 16 import regex | |
| 17 import string | |
| 18 import getopt | |
| 19 | |
| 20 pat = '^\([a-zA-Z0-9 :]*\)!\(.*\)!\(.*\)!\([<>].*\)!\([0-9]+\)!\([0-9]+\)$' | |
| 21 prog = regex.compile(pat) | |
| 22 | |
| 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, ':', `line` | |
| 64 continue | |
| 65 items = prog.group(1, 2, 3, 4, 5, 6) | |
| 66 logtime, loguser, loghost, logfile, logbytes, logxxx2 = items | |
| 67 ## print logtime | |
| 68 ## print '-->', loguser | |
| 69 ## print '--> -->', loghost | |
| 70 ## print '--> --> -->', logfile | |
| 71 ## print '--> --> --> -->', logbytes | |
| 72 ## print '--> --> --> --> -->', logxxx2 | |
| 73 ## for i in logtime, loghost, logbytes, logxxx2: | |
| 74 ## if '!' in i: print '???', i | |
| 75 add(bydate, logtime[-4:] + ' ' + logtime[:6], items) | |
| 76 add(bytime, logtime[7:9] + ':00-59', items) | |
| 77 direction, logfile = logfile[0], logfile[1:] | |
| 78 # The real path probably starts at the last //... | |
| 79 while 1: | |
| 80 i = string.find(logfile, '//') | |
| 81 if i < 0: break | |
| 82 logfile = logfile[i+1:] | |
| 83 add(byfile, logfile + ' ' + direction, items) | |
| 84 logdir = os.path.dirname(logfile) | |
| 85 ## logdir = os.path.normpath(logdir) + '/.' | |
| 86 while 1: | |
| 87 add(bydir, logdir + ' ' + direction, items) | |
| 88 dirhead = os.path.dirname(logdir) | |
| 89 if dirhead == logdir: break | |
| 90 logdir = dirhead | |
| 91 add(byhost, loghost, items) | |
| 92 add(byuser, loguser, items) | |
| 93 add(bytype, direction, items) | |
| 94 except KeyboardInterrupt: | |
| 95 print 'Interrupted at line', lineno | |
| 96 show(bytype, 'by transfer direction', maxitems) | |
| 97 show(bydir, 'by directory', maxitems) | |
| 98 show(byfile, 'by file', maxitems) | |
| 99 show(byhost, 'by host', maxitems) | |
| 100 show(byuser, 'by user', maxitems) | |
| 101 showbar(bydate, 'by date') | |
| 102 showbar(bytime, 'by time of day') | |
| 103 | |
| 104 def showbar(dict, title): | |
| 105 n = len(title) | |
| 106 print '='*((70-n)/2), title, '='*((71-n)/2) | |
| 107 list = [] | |
| 108 keys = dict.keys() | |
| 109 keys.sort() | |
| 110 for key in keys: | |
| 111 n = len(str(key)) | |
| 112 list.append((len(dict[key]), key)) | |
| 113 maxkeylength = 0 | |
| 114 maxcount = 0 | |
| 115 for count, key in list: | |
| 116 maxkeylength = max(maxkeylength, len(key)) | |
| 117 maxcount = max(maxcount, count) | |
| 118 maxbarlength = 72 - maxkeylength - 7 | |
| 119 for count, key in list: | |
| 120 barlength = int(round(maxbarlength*float(count)/maxcount)) | |
| 121 bar = '*'*barlength | |
| 122 print '%5d %-*s %s' % (count, maxkeylength, key, bar) | |
| 123 | |
| 124 def show(dict, title, maxitems): | |
| 125 if len(dict) > maxitems: | |
| 126 title = title + ' (first %d)'%maxitems | |
| 127 n = len(title) | |
| 128 print '='*((70-n)/2), title, '='*((71-n)/2) | |
| 129 list = [] | |
| 130 keys = dict.keys() | |
| 131 for key in keys: | |
| 132 list.append((-len(dict[key]), key)) | |
| 133 list.sort() | |
| 134 for count, key in list[:maxitems]: | |
| 135 print '%5d %s' % (-count, key) | |
| 136 | |
| 137 def add(dict, key, item): | |
| 138 if dict.has_key(key): | |
| 139 dict[key].append(item) | |
| 140 else: | |
| 141 dict[key] = [item] | |
| 142 | |
| 143 main() |
