Skip to content

Instantly share code, notes, and snippets.

@gdugas
Created September 6, 2013 15:04
Show Gist options
  • Save gdugas/6465087 to your computer and use it in GitHub Desktop.
Save gdugas/6465087 to your computer and use it in GitHub Desktop.
Postfix log parser: parse postfix mail.log, store only send and reception results in 'messages' attributes.
class Parser(object):
PATTERN = r"^" \
+ r"(?P<month>\w{3})\s+" \
+ r'(?P<day>\d{1,2})\s+' \
+ r'(?P<time>\d{2}:\d{2}:\d{2})\s+' \
+ r'(?P<hostname>[^\s]+)\s+' \
+ r'(?P<exec>\w+/\w+)' \
+ r'\[(?P<port>\d+)\]:\s+' \
+ r'(?P<message_id>\w+):\s+' \
+ r'(?P<info>.*)$'
def parse(self, fh, year=None, date_format=None):
from datetime import datetime
import re
now = datetime.now()
year = year or now.year
date_format = date_format or "%Y %b %d %H:%M:%S"
self.messages = messages = {}
compiled = re.compile(self.PATTERN)
patterns = {
'client': re.compile(r'^(?P<host>.*)\[(?P<ip>[\w.]+)\]')
}
for line in fh:
m = compiled.match(line)
if m:
d = m.groupdict()
row_date_str = "%.4d %s %.2d %s" % (year,
d['month'],
int(d['day']),
d['time'])
row_date = datetime.strptime(row_date_str,
date_format)
if not d['message_id'] in messages:
messages[d['message_id']] = {}
msg = messages[d['message_id']]
if d['exec'].startswith('postfix/'):
subexec = d['exec'].split('/')[1]
if subexec in ['smtp', 'local']:
receiver = {}
kvs = d['info'].split(',')
for kv in kvs:
key, value = kv.strip().split('=')
receiver[key] = value
receiver['date'] = row_date
if not 'receiver' in msg:
msg['receiver'] = []
msg['receiver'].append(receiver)
elif subexec in ['smtpd', 'qmgr']:
kvs = d['info'].split(',')
for kv in kvs:
if kv.find('=') == -1: continue
key, value = kv.strip().split('=')
if key == 'client':
m = patterns['client'].match(value)
msg['date'] = row_date
if m:
d = m.groupdict()
msg['remote_host'] = d['host']
msg['remote_ip'] = d['ip']
elif key == 'sasl_method':
msg['login_method'] = value
elif key == 'sasl_username':
msg['sender_login'] = value
elif key in 'size':
msg['size'] = int(value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment