#!/usr/bin/python ''' sagator's logwatch script (c) 2003-2005 Jan ONDREJ (SAL) <ondrejj(at)salstar.sk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ''' import sys,re,os,time def kilomega(x,v='B'): if x>=1024*1024: return "%1.4f M%s" % (x/1024.0/1024.0,v) elif x>=1024: return "%1.4f k%s" % (x/1024.0,v) else: return "%1.4f %s " % (x,v) def hodminsec(t): return "%d:%02d:%02d" % (t/60/60,t/60%60,t%60) class a: connect=0 count,bytes=0,0 time=0 found={} found_bytes={} clean,clean_bytes=0,0 infected,infected_bytes=0,0 spam,spam_bytes=0,0 errors=0 erra={} warnings=0 warna={} def spamstring(s): return (s[:4]=='SPAM') or (s[-5:]=='&SPAM') try: DATE_RANGE=os.environ['LOGWATCH_DATE_RANGE'] except KeyError: DATE_RANGE='today' # regular expressions base='^ *([0-9]+): ' reg_conn=re.compile(base+ 'Connection from: ').search reg_stats=re.compile(base+ 'STATS: ([0-9.]+) seconds, ([0-9]+) bytes, status: (.*)$').search if DATE_RANGE=='yesterday': searchdate=time.strftime("%a %b %e ..:..:.. %Y", time.localtime(time.time()-86400)) elif DATE_RANGE=='today': searchdate=time.strftime("%a %b %e ..:..:.. %Y") elif DATE_RANGE=='all': searchdate='... ... .. ..:..:.. ....' reg_aconn=re.compile(base+'Connection from: ').search reg_conn=re.compile(base+'Connection from: .* at ('+searchdate+')').search reg_exit=re.compile(base+'Child exited ... pid,status: .([0-9]*),').search reg_err=re.compile(base+'([-a-zA-Z_()]*): *(ERROR|WARNING)[: ]*(.*)$').search pids={} while True: line=sys.stdin.readline() # EOF? if not line: break # add a new PID into DB rconn=reg_aconn(line) if rconn: reg1=reg_conn(line) if reg1: a.connect+=1 pids[reg1.group(1)]=reg1.group(2) else: # It is a new connection from this pid, but not for date range # If in pids, remove it. try: del pids[rconn.group(1)] except KeyError: pass # remove PID from DB if exited reg2=reg_exit(line) if reg2: try: del pids[reg2.group(2)] except: pass reg=reg_err(line) if reg: # is this PID in DB? if not pids.has_key(reg.group(1)): continue # is it an ERROR or WARNING? if reg.group(3)=="ERROR": # error a.errors+=1 try: a.erra[reg.group(4)]+=1 except KeyError: a.erra[reg.group(4)]=1 else: # warning a.warnings+=1 try: a.warna[reg.group(4)]+=1 except KeyError: a.warna[reg.group(4)]=1 reg=reg_stats(line) if reg: # is this PID in DB? if not pids.has_key(reg.group(1)): continue a.count+=1 a.time+=float(reg.group(2)) bytes=reg.group(3) name=reg.group(4) a.bytes+=int(bytes) if (len(name)>55) and (not spamstring(name)): # error? a.errors+=1 try: a.erra[name]+=1 except KeyError: a.erra[name]=1 elif name=='CLEAN': a.clean+=1 a.clean_bytes+=int(bytes) else: if spamstring(name): a.spam+=1 a.spam_bytes+=int(bytes) else: a.infected+=1 a.infected_bytes+=int(bytes) try: a.found[name]+=1 a.found_bytes[name]+=int(bytes) except KeyError: a.found[name]=1 a.found_bytes[name]=int(bytes) #print '\n--------------------- SAGATOR -----------------------\n' if a.count>0: print ' Email count Bytes' print 'Total: %6d %12s' % \ (a.count,kilomega(a.bytes)) if a.bytes==0: a.bytes=0.00001 print 'Clean: %6d [%3d%%] %12s [%3d%%]' % \ (a.clean, a.clean*100/a.count, kilomega(a.clean_bytes), a.clean_bytes*100/a.bytes) print 'Viruses: %6d [%3d%%] %12s [%3d%%]' % \ (a.infected, a.infected*100/a.count, kilomega(a.infected_bytes), a.infected_bytes*100/a.bytes) print 'Spams: %6d [%3d%%] %12s [%3d%%]' % \ (a.spam, a.spam*100/a.count, kilomega(a.spam_bytes), a.spam_bytes*100/a.bytes) print '' print 'Consumed time: %8s' % (hodminsec(a.time)) print 'Connections: %6d' % (a.connect) keys=a.found.keys() if keys: keys.sort(key=lambda x: (a.found[x], a.found_bytes[x], x), reverse=True) print '' for k in keys: print '%6d [%12s]: %s' % (a.found[k],kilomega(a.found_bytes[k]),k) if a.errors>0: print '\nErrors: %d' % a.errors for k,v in a.erra.items(): print "%5d: %s" % (v,k) if a.warnings>0: print '\nWarnings: %d' % a.warnings for k,v in a.warna.items(): print "%5d: %s" % (v,k) #print '\n--------------------- SAGATOR -----------------------\n'