#! /usr/bin/env python # # Smail logfile analyzer # # Copyright (c) 1999 A E Wrede # # Version 0.7 # # should now support message format from smail version 3.2.0.98 to .106 import os, sys, string, time, getopt LOGFILE='/var/log/smail/logfile' helpflag=0 unknownflag=0 verboseflag=0 optlist=[] args=[] typelist=[] allflag=0 try: optlist, args = getopt.getopt(sys.argv[1:], 'ahl:uv') except: helpflag=1 for o,a in optlist: if o == '-a': allflag=1 elif o == '-h': helpflag=1 elif o == '-l': typelist.append(a) elif o == '-u': unknownflag=1 elif o == '-v': verboseflag=verboseflag + 1 if helpflag: print "usage:",sys.argv[0]," [-vh] [logfile ...]" print " -h help, print this text" print " -l list records of type " print " -a list all records" print " -v list messages" sys.exit(1) if len(args) == 0: logfiles=[LOGFILE] else: logfiles=args msgs={} counts={} firsttime=0 lasttime=0 deliverytime=0 deliverycount=0 completedtime=0 completedcount=0 tsize=0 for logfile in logfiles: f=open(logfile,'r') while 1: l=f.readline() if len(l) == 0: break a=string.split(l[:-1]) try: dt=time.strptime(string.join(a[0:2]),"%m/%d/%Y %H:%M:%S:") if firsttime > time.mktime(dt) or firsttime == 0: firsttime=time.mktime(dt) if lasttime < time.mktime(dt) or lasttime == 0: lasttime=time.mktime(dt) id=a[2] key=a[3] try: key2=a[4] except: key2='' except: dt='0' id='-' key='Unknown' if key == 'remote': # smail v3.2.0.106 id='remote' key=a[4] key2=a[5] if id == 'remote': if key == 'connection': key='Daemon Connect' elif key in ['HELO:', 'EHLO:']: if key2 == 'invalid': key='HELO Error' elif key2 == 'questionable': key='HELO Warning' else: key='Unknown' elif key == 'MAIL': key='Rejected' elif key == 'RCPT': key='Refused' elif string.find(l,'security violation') >= 0: key='Security' else: key='Unknown' id='-' if id == 'pid': if string.join(a[4:7]) == 'smail daemon started': key='Daemon Restart' elif string.join(a[4:8]) == 'SIGTERM received, shutting down': key='Daemon Shutdown' elif string.join(a[4:7]) == 'new config files,': key='Daemon Reload' else: key='Unknown' id='-' if id == 'SMTP': if key == 'connection': if key2 == 'timeout': key='SMTP timeout' else: key='SMTP connection' else: key='SMTP error' if key in ['Returned','Sent']: key='Bounced' if key in ['SMTP']: key='Protocol' if key == "Completed.": key="Completed" if not counts.has_key(key): counts[key]=1 else: counts[key]=counts[key]+1 # if not key in ['Received','Delivered','Completed','Failed','Deferred', # 'Error','Warning','Bounced','Protocol','Daemon Connect','Daemon Security', # 'Daemon Restart','Daemon Shutdown','Daemon Reload']: # key='Unknown' if allflag or key in typelist: print l[:-1] if key == 'Unknown': continue msg={'Time': dt} msg['Type']=key if key in ['Received','Delivered','Completed','Failed', 'Bounced','Deferred']: if key == 'Failed': for i in a[4:7]: x=string.split(i,':') if x[0] == 'SIZE': tsize=tsize + string.atoi(x[1]) msg[x[0]]=string.join(x[1:]) x=string.split(string.join(a[7:]),':') msg[x[0]]=string.join(x[1:]) else: for i in a[4:]: x=string.split(i,':') if x[0] == 'SIZE': tsize=tsize + string.atoi(x[1]) msg[x[0]]=string.join(x[1:]) elif key == 'mail': msg['Type']='Disposed' msg['Moved To']=a[6] else: msg['OTHER']=string.join(a[3:]) if not msgs.has_key(id): msgs[id]=[msg] else: msgs[id].append(msg) f.close() for i in msgs.keys(): rtime=0 for j in msgs[i]: if j['Type'] == 'Received': rtime=time.mktime(j['Time']) elif j['Type'] in ['Delivered','Completed']: if rtime > 0: dtime=time.mktime(j['Time']) - rtime if j['Type'] == 'Delivered': deliverytime=deliverytime + dtime deliverycount=deliverycount + 1 else: completedtime=completedtime + dtime completedcount=completedcount + 1 if verboseflag: for i in msgs.keys(): if unknownflag == 0 and i == "-": continue print "" print "Message",i+":" for j in msgs[i]: delta='' if j['Type'] == 'Received': rtime=time.mktime(j['Time']) elif j['Type'] in ['Delivered','Completed','Failed','Bounced','Deferred','Disposed']: dtime=time.mktime(j['Time']) - rtime delta="(%0.0f sec after receiving)" % dtime print " ",j['Type'],time.asctime(j['Time']),delta for k in j.keys(): if not k in ['Type','Time']: print " ",k,": ",j[k] secs=lasttime - firsttime if secs == 0: secs=1 mins=secs / 60.0 print "first log entry:", time.asctime(time.localtime(firsttime)) print "last log entry: %s for %0.0f Minutes" % (time.asctime(time.localtime(lasttime)), mins) print "" print "Record Counts by Type" print "%-20s %5s %5s" % ("Type", "Count", "Rate/Min") print "%-20s %5s %5s" % ("----", "-----", "--------") r=counts.keys() r.sort() for i in r: print "%-20s %5d %8.1f" % (i, counts[i], (counts[i] + 0.0)/mins), if i == 'Received': print " %d KBytes" % (tsize / 1024) else: print if deliverytime > 0: print "Average delivery time: %0.1f seconds" % ( deliverytime / deliverycount) if completedtime > 0: print "Average completed time: %0.1f seconds" % ( completedtime / completedcount) .