#!/usr/bin/python display_limit = 20 qmail_send_log_dir = "/var/log/qmail/send/" msg_threshold = 50 # Email settings SERVER = "localhost" FROM = "myemail@mydomain.com" TO = ["myemail@mydomain.com"] # must be a list SUBJECT = "QMail Send Threhold Report" import sys, re, os import time import smtplib from datetime import datetime email_number_data = {} if (len(sys.argv) > 1): check_date = datetime(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3])) else: check_date = datetime.now() def decode_tai64n(num): """ decodes a tai64 timestamp into a python datetime object """ sNum = str(num).replace("@", "") sNum = sNum[1:-8] lNum = int(sNum, 16) return datetime.fromtimestamp(lNum) def encode_tai64n(dateTime): """ encodes a python datetime object into a tai64n string (hack) """ unixTimeStamp = "@40000000" + hex(int(time.mktime(dateTime.timetuple()))) + "000000" return unixTimeStamp def sizeof_fmt(num): """ formats bytes to sometnhing more human readable """ for x in ['bytes','KB','MB','GB']: if num < 1024.0: return "%3.1f%s" % (num, x) num /= 1024.0 return "%3.1f%s" % (num, 'TB') def dict_key_sort(input_dict): """ returns a dictionary sorted by keys """ key_list = input_dict.items() key_list.sort() key_list.reverse() outputDict = {} for item in key_list: outputDict[item[0]] = item[1] return outputDict def dict_value_sort(input_dict): """ Returns the keys of dictionary d sorted by their values """ key_list = input_dict.items() dict_items = [ [v[1],v[0]] for v in key_list] dict_items.sort() dict_items.reverse() return [ dict_items[i][1] for i in range(0,len(dict_items))] def parse_logfile (file, filename): """ parses a file searches for message line and adds it to the dictionary """ global email_number_data previous_midnight = datetime( check_date.year, check_date.month, check_date.day ) current_midnight = datetime( check_date.year, check_date.month, check_date.day, 23,59,59 ) for line in file: if "info msg" in line: re_email = re.compile("<.*>") email_match = re_email.search(line) re_size = re.compile("bytes .* from") size_match = re_size.search(line) splitSpaces = line.split(" ") if splitSpaces[0][0] == "@": dateTime = decode_tai64n(splitSpaces[0].replace("@", "")) else: print "none tai64n date encodings not yet supported" email_match_val = "" size_match_val = 0 if email_match and previous_midnight < dateTime and current_midnight > dateTime: email_match_val = str(email_match.group()) email_match_val = email_match_val.replace("<", "") email_match_val = email_match_val.replace(">", "") email_match_val = email_match_val.replace(" ", "") email_match_val = email_match_val.lower() if size_match and previous_midnight < dateTime and current_midnight > dateTime: size_match_val = str(size_match.group()) size_match_val = size_match_val.replace("bytes ", "") size_match_val = size_match_val.replace(" from", "") size_match_val = int(size_match_val) if email_match_val != "" and size_match_val > 0: if email_match_val in email_number_data: email_number_data[email_match_val] += 1 else: email_number_data[email_match_val] = 1 def send_email(sender, receiver, subject, body): msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" %(sender, receiver, subject, body)) s = smtplib.SMTP('localhost') s.sendmail(sender, [receiver], msg) s.quit() def display_stats(): """ Display the data """ sorted_email_number_data = dict_value_sort(email_number_data) lCount = 0 print "" print "=========== Email Number Data ============ " for Key in sorted_email_number_data: if email_number_data[Key] > msg_threshold: print Key + ": " + str(email_number_data[Key]) TEXT = Key + " has sent " + str(email_number_data[Key]) + " messages (threshold: " + str(msg_threshold) + ")" send_email(FROM,TO,SUBJECT,TEXT) lCount += 1 if lCount > display_limit: break print "" def logfile_is_within_range(file_name, file_path): previous_midnight = datetime( check_date.year, check_date.month, check_date.day ) current_midnight = datetime( check_date.year, check_date.month, check_date.day, 23,59,59 ) if file_name[0] == "@": file_date = datetime.fromtimestamp(os.path.getmtime(file_path)) if file_date > previous_midnight and file_date < current_midnight: return True else: return False else: if file_name == "current": return True; else: # Not a searchable log file return False print "Displaying data for " + str(check_date) for file_name in os.listdir(qmail_send_log_dir): if logfile_is_within_range(file_name, qmail_send_log_dir + file_name): file = open(qmail_send_log_dir + file_name) print "processing " + qmail_send_log_dir + file_name parse_logfile(file, qmail_send_log_dir + file_name) file.close() display_stats()