Very basic Syslog server in Python that accepts messages in RFC3164 and RFC5424 format. This has only been tested with Rsyslog on Linux and Cisco IOS syslog. Other implementations may send mesages in slightly different format than the two regular expressions at the top of the script will match. In particular there are apparently many implementations that deviate from strict RFC3164.
from __future__ import print_function
import re
import socket
import arrow
RFC_3164 = re.compile('<(?P<pri>\d+)>\s*(?P<timestamp>\S{3}\s\d{2}\s+\d{2}:\d{2}:\d{2})\s+(?P<host>\S+)\s+(?P<tag>[^\[\s\:]+)\[*(?P<procid>\d*)\]*:*\s+(?P<msg>.*)')
RFC_5424 = re.compile('<(?P<pri>\d+)>(?P<version>\d+)\s+(?P<timestamp>\S+)\s+(?P<host>\S+)\s+(?P<tag>\S+)\s+(?P<procid>\S+)\s+(?P<msgid>\S+)\s+-\s+(?P<msg>.*)')
CISCO_IOS = re.compile('<(?P<pri>\d+)>\d*:\s*\.*(?P<timestamp>\S{3}\s\d{2}\s+\d{2}:\d{2}:\d{2}\.\d{3}):\s+(?P<tag>\S+)\s+(?P<msg>.*)')
RFC_3164_TIMEFMT = 'MMM DD HH:mm:ss'
RFC_5424_TIMEFMT = None
CISCO_IOS_TIMEFMT = 'MMM DD HH:mm:ss.SSS'
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 514))
SEVERITY = {0: 'emergency',
1: 'alert',
2: 'critical',
3: 'error',
4: 'warning',
5: 'notice',
6: 'info',
7: 'debug'}
FACILITY = {0: 'kernel',
1: 'user',
2: 'mail',
3: 'daemon',
4: 'auth',
5: 'syslog',
6: 'lpr',
7: 'news',
8: 'uucp',
9: 'cron',
10: 'authpriv',
11: 'ftp',
12: 'ntp',
13: 'security',
14: 'console',
15: 'solaris-cron',
16: 'local0',
17: 'local1',
18: 'local2',
19: 'local3',
20: 'local4',
21: 'local5',
22: 'local6',
23: 'local7'}
while True:
data, addr = sock.recvfrom(1500)
NOW = arrow.now()
srcip,sport = addr
m = None
for regex,timefmt in ( (RFC_3164,RFC_3164_TIMEFMT),
(RFC_5424, RFC_5424_TIMEFMT),
(CISCO_IOS, CISCO_IOS_TIMEFMT) ):
m = regex.search(data)
if m:
break
if not m:
raise ValueError(data)
groups = m.groupdict()
pri = int(groups.get('pri', 0))
facility = int(pri/8)
severity = pri - (facility * 8)
facility_name = FACILITY.get(facility, None)
severity_name = SEVERITY.get(severity, None)
version = int(groups.get('version', 0))
timestamp = groups.get('timestamp', None)
host = groups.get('host', srcip)
tag = groups.get('tag', None)
procid = groups.get('procid', None)
msgid = groups.get('msgid', None)
msg = groups.get('msg', None)
if timefmt:
timestamp = arrow.get(timestamp, timefmt).replace(year=NOW.year)
else:
timestamp = arrow.get(timestamp)
# Correct timezone
if timestamp.hour == NOW.hour and timestamp.minute == NOW.minute:
timestamp = timestamp.replace(tzinfo=NOW.tzinfo)
else:
timestamp = timestamp.to(NOW.tzinfo)
print(facility_name, severity_name, version, timestamp, host, tag, procid, msgid, msg)
```