Skip to content

Instantly share code, notes, and snippets.

@adiroiban
Forked from gleicon/txsyslogd.py
Last active September 10, 2015 12:51
Show Gist options
  • Save adiroiban/3a66dc285d75cc6310da to your computer and use it in GitHub Desktop.
Save adiroiban/3a66dc285d75cc6310da to your computer and use it in GitHub Desktop.
minimalistic syslog daemon written with twisted.
#!/usr/bin/python
#
# Simple syslog collector used for testing.
#
from twisted.internet import address, reactor, stdio, defer
from twisted.internet.protocol import DatagramProtocol, Protocol, Factory
from twisted.protocols.basic import LineReceiver
import time, re, math, json
#<22>Nov 1 00:12:04 gleicon-vm1 postfix/smtpd[4880]: connect from localhost[127.0.0.1]
severity = [
'emerg',
'alert',
'crit',
'err',
'warn',
'notice',
'info',
'debug',
]
facility = [
'kern',
'user',
'mail',
'daemon',
'auth',
'syslog',
'lpr',
'news',
'uucp',
'cron',
'authpriv',
'ftp',
'ntp',
'audit',
'alert',
'at',
'local0',
'local1',
'local2',
'local3',
'local4',
'local5',
'local6',
'local7',
]
fs_match = re.compile("<(.+)>(.*)", re.I)
class SyslogMixin(object):
"""
Shared code for handling Syslog received lines.
"""
def lineReceived(self, line):
k = {}
k['line'] = line.strip()
(fac, sev) = self._calc_lvl(k['line'])
peer = self.transport.getHost()
if isinstance(peer, address.UNIXAddress):
k['host'] = peer.name
else:
k['host'] = peer.host
k['tstamp'] = time.time()
k['facility'] = fac
k['severity'] = sev
print json.dumps(k)
def _calc_lvl(self, line):
lvl = fs_match.split(line)
if lvl and len(lvl) > 1:
i = int(lvl[1])
fac = int(math.floor(i / 8))
sev = i - (fac * 8)
return (facility[fac], severity[sev])
return (None, None)
class SyslogdUDPProtocol(DatagramProtocol, SyslogMixin):
"""
Simple Syslog handler over UDP.
It assumes full message is received in the same datagram.
"""
def datagramReceived(self, data, peer):
print 'UDP connection from %s' % (peer,)
lines = data.split('\x00')
for line in lines:
if not line:
continue
self.lineReceived(line)
# SyslogMixin need to come first.
class SyslogdStreamProtocol(SyslogMixin, LineReceiver):
"""
Handle Syslog over stream protocols TCP/Unix socket.
"""
delimiter = '\x00'
def connectionMade(self):
print 'Stream connection from %r' % self.transport.getHost()
class SyslogdFactory(Factory):
protocol = SyslogdStreamProtocol
def main():
reactor.listenUDP(10514, SyslogdUDPProtocol())
# reactor.listenTCP(10415, SyslogdTCPFactory())
# reactor.listenUNIX('/tmp/syslog', SyslogdFactory())
reactor.run()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment