#!/usr/bin/python3 ''' salpack-maillog Usage: salpack-maillog [-h|-a|-v] [maillog_filename|-j|-j=since] ''' import re, sys, os emails = {} qids = [] verbose = False def getemail(s): try: return re.compile("[<>]").split(s)[1] except IndexError: print(s) raise ignore1 = [ "connect", "disconnect", "certificate verification failed", "SSL_accept error", "SSL_connect error", "connect from", "disconnect from", "lost connection after AUTH from", "improper command pipelining", ] ignore2 = [ "message-id=", "client=", "host ", "resent-message-id=", "enabling PIX workarounds", "skipped", "lost connection with", "sender delay notification", ] def check_ignore(column, texts): for t in texts: if column.startswith(t): return True return False def processlog(logfile): if logfile.startswith("-j"): # use journal args = logfile.split("=", 1) if len(args)==1: since = "-1 day" else: since = args[1] f = os.popen("journalctl -u postfix --since='%s'" % since, "r") else: if os.path.getsize(logfile)==0: print("WARNING: Empty file: %s" % logfile) if sys.version_info[0]>2: f = open(logfile, "r", encoding="utf-8", errors="ignore") else: f = open(logfile) for line in f.readlines(): cols = line.strip().split(": ") if "postfix/" in cols[0]: if cols[1] in ["warning", "statistics", "fatal"]: continue elif len(cols)<3: continue elif cols[2] in ["removed", "reject", "sender non-delivery notification"]: continue elif check_ignore(cols[1], ignore1): continue elif check_ignore(cols[2], ignore2): continue qid = cols[1] if qid not in emails: emails[qid] = {"dt": cols[0][:15]} qids.append(qid) if cols[2].startswith("uid="): emails[qid]["from"] = getemail(cols[2].split(" ", 1)[-1]) elif cols[2].startswith("from="): emails[qid]["from"] = getemail(cols[2]) elif cols[2].startswith("to="): emails[qid]["to"] = getemail(cols[2]) if len(cols)>3 and cols[3].startswith("orig_to="): emails[qid]["orig_to"] = getemail(cols[3]) elif verbose: print(cols) if "-h" in sys.argv or "--help" in sys.argv: print(__doc__) sys.exit() if "-v" in sys.argv: verbose = True sys.argv.remove("-v") if "-a" in sys.argv: sys.argv.remove("-a") logs = [ os.path.join("/var/log", x) for x in os.listdir("/var/log") if x.startswith("maillog-") ] for log in logs: processlog(log) if sys.argv[1:]: for log in sys.argv[1:]: processlog(log) else: processlog("/var/log/maillog") for queue_id in qids: email = emails[queue_id] orig = email.get("orig_to") if orig: orig = "(" + orig + ")" else: orig = "" print( "%s: %s -> %s%s [%s]" % (email.get("dt"), email.get("from"), email.get("to"), orig, queue_id) )