/Demo/scripts/ftpstats.py

http://unladen-swallow.googlecode.com/ · Python · 145 lines · 116 code · 10 blank · 19 comment · 30 complexity · 710d30da42671b2022512b9c95e10708 MD5 · raw file

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