Add initial scaffolding for log parsing and connection classes
This commit is contained in:
Родитель
33f18b392d
Коммит
113be34933
|
@ -0,0 +1,57 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class Connection:
|
||||||
|
def __init__(self, conn_id):
|
||||||
|
self.conn_id = conn_id
|
||||||
|
self.tls = False
|
||||||
|
self.client = ""
|
||||||
|
self.time = ""
|
||||||
|
self.fd = ""
|
||||||
|
self.op = ""
|
||||||
|
self.verb = ""
|
||||||
|
self.verb_details = ""
|
||||||
|
|
||||||
|
# Something happened, this method's job is to update the context
|
||||||
|
def add_event(self, event):
|
||||||
|
self.time = event['time']
|
||||||
|
self.server = event['server']
|
||||||
|
self.process = event['process']
|
||||||
|
self.add_rest(event['rest'])
|
||||||
|
|
||||||
|
def add_accept(self, verb_details):
|
||||||
|
# Example: from IP=192.168.1.1:56822 (IP=0.0.0.0:389)
|
||||||
|
pattern = r'^from IP=(\d+\.\d+\.\d+\.\d+)'
|
||||||
|
match = re.search(pattern, verb_details)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
self.client = match[1]
|
||||||
|
else:
|
||||||
|
raise Exception('Failed to parse: {}'.format(verb_details))
|
||||||
|
|
||||||
|
def add_rest(self, rest):
|
||||||
|
self.fd = ""
|
||||||
|
self.op = ""
|
||||||
|
self.verb = ""
|
||||||
|
self.verb_details = ""
|
||||||
|
|
||||||
|
# Example: fd=34 ACCEPT ...
|
||||||
|
pattern = r'^(\w+)=(\d+) (\w+)\s?(.*)$'
|
||||||
|
match = re.search(pattern, rest)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
if match[1] == 'fd':
|
||||||
|
self.fd = int(match[2])
|
||||||
|
elif match[1] == 'op':
|
||||||
|
self.op = int(match[2])
|
||||||
|
else:
|
||||||
|
raise Exception('Unsupported option: {}'.format(match[1]))
|
||||||
|
|
||||||
|
self.verb = match[3]
|
||||||
|
self.verb_details = match[4]
|
||||||
|
|
||||||
|
if self.verb == "ACCEPT":
|
||||||
|
self.add_accept(self.verb_details)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception('Failed to parse: {}'.format(rest))
|
|
@ -0,0 +1,18 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class RawLogParser:
|
||||||
|
def parse(self, line):
|
||||||
|
# This regex takes a raw log and parses it into a few elements
|
||||||
|
# time, server, process, and arbitrary remainder
|
||||||
|
pattern = r'^(\w+ \d+ \d+:\d+:\d+) ([a-zA-Z0-9\.]+) (\w+\[\d+\]): conn=(\d+) (.*)$'
|
||||||
|
match = re.search(pattern, line)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
return {'time': match[1],
|
||||||
|
'server': match[2],
|
||||||
|
'process': match[3],
|
||||||
|
'conn': match[4],
|
||||||
|
'rest': match[5]}
|
||||||
|
else:
|
||||||
|
raise Exception('Failed to parse raw line: {}'.format(line))
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from connection import Connection
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class TestConnection():
|
||||||
|
def test_creation(self):
|
||||||
|
connection = Connection(1245)
|
||||||
|
assert isinstance(connection, Connection)
|
||||||
|
assert connection.conn_id == 1245
|
||||||
|
|
||||||
|
def test_parse_rest(self):
|
||||||
|
rest = 'fd=34 ACCEPT from IP=192.168.1.1:56822 (IP=0.0.0.0:389)'
|
||||||
|
|
||||||
|
connection = Connection(1245)
|
||||||
|
connection.add_rest(rest)
|
||||||
|
|
||||||
|
assert connection.conn_id == 1245
|
||||||
|
assert connection.fd == 34
|
||||||
|
assert connection.op == ""
|
||||||
|
assert connection.verb == "ACCEPT"
|
||||||
|
assert connection.verb_details == "from IP=192.168.1.1:56822 (IP=0.0.0.0:389)"
|
||||||
|
assert connection.client == "192.168.1.1"
|
||||||
|
|
||||||
|
def test_add_event(self):
|
||||||
|
event = {'time': 'Oct 26 12:46:58',
|
||||||
|
'server': 'ldap.example.com',
|
||||||
|
'process': 'slapd[11086]',
|
||||||
|
'conn': '6862452',
|
||||||
|
'rest': 'fd=34 ACCEPT from IP=192.168.1.1:56822 (IP=0.0.0.0:389)'}
|
||||||
|
|
||||||
|
connection = Connection(1245)
|
||||||
|
connection.add_event(event)
|
||||||
|
assert connection.time == event["time"]
|
||||||
|
assert connection.server == event["server"]
|
||||||
|
assert connection.process == event["process"]
|
||||||
|
assert connection.conn_id == 1245
|
||||||
|
assert connection.fd == 34
|
||||||
|
assert connection.op == ""
|
||||||
|
assert connection.verb == "ACCEPT"
|
||||||
|
assert connection.verb_details == "from IP=192.168.1.1:56822 (IP=0.0.0.0:389)"
|
||||||
|
assert connection.client == "192.168.1.1"
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from rawlogparser import RawLogParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestRawLogParser():
|
||||||
|
def test_line(self):
|
||||||
|
log_line = "Oct 26 12:46:58 ldap.example.com slapd[11086]: conn=6862452 fd=34 ACCEPT from IP=192.168.1.1:56822 (IP=0.0.0.0:389)"
|
||||||
|
raw_log_parser = RawLogParser()
|
||||||
|
expectation = {'time': 'Oct 26 12:46:58',
|
||||||
|
'server': 'ldap.example.com',
|
||||||
|
'process': 'slapd[11086]',
|
||||||
|
'conn': '6862452',
|
||||||
|
'rest': 'fd=34 ACCEPT from IP=192.168.1.1:56822 (IP=0.0.0.0:389)'}
|
||||||
|
|
||||||
|
assert raw_log_parser.parse(log_line) == expectation
|
Загрузка…
Ссылка в новой задаче