From b75671e68c333f802c31cf5d3dfcf16479de7196 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Oct 2021 18:51:10 +0200 Subject: [PATCH] Logger and config setup. Logger also pushes to elastic --- config.yaml | 11 ++++++++ logger.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.py | 23 ++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 config.yaml create mode 100644 logger.py create mode 100644 utils.py diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..855ecda --- /dev/null +++ b/config.yaml @@ -0,0 +1,11 @@ +logger: + name: brewlogger + ch_level: INFO + +elastic: + host: elastic.schleppe + port: 9200 + ssl: True + +database: + name: brew.db diff --git a/logger.py b/logger.py new file mode 100644 index 0000000..6384572 --- /dev/null +++ b/logger.py @@ -0,0 +1,79 @@ +#!/bin/usr/python3 + +import logging +import os +import json +import uuid +from datetime import datetime, date +import urllib.request + +from utils import getConfig + +config = getConfig() +LOGGER_NAME = config['logger']['name'] +esHost = config['elastic']['host'] +esPort = config['elastic']['port'] + +class ESHandler(logging.Handler): + def __init__(self, *args, **kwargs): + self.host = kwargs.get('host') + self.port = kwargs.get('port') or 9200 + self.date = date.today() + self.sessionID = uuid.uuid4() + + logging.StreamHandler.__init__(self) + + def emit(self, record): + self.format(record) + timestamp = datetime.fromtimestamp(record.created).strftime('%Y-%m-%dT%H:%M:%S.%f+02:00') + + indexURL = 'http://{}:{}/{}-{}/_doc'.format(self.host, self.port, LOGGER_NAME, self.date.strftime('%Y.%m.%d')) + + doc = { + 'severity': record.levelname, + 'message': record.message, + '@timestamp': timestamp, + 'sessionID': str(self.sessionID) + } + + if hasattr(record, 'es'): + for param in record.es.values(): + if ': {}'.format(param) in record.message: + doc['message'] = record.message.replace(': {}'.format(str(param)), '') + + doc = {**record.es, **doc} + + payload = json.dumps(doc).encode('utf8') + req = urllib.request.Request(indexURL, data=payload, + headers={'content-type': 'application/json'}) + response = urllib.request.urlopen(req) + response = response.read().decode('utf8') + return response + +class ElasticFieldParameterAdapter(logging.LoggerAdapter): + def __init__(self, logger, extra={}): + super().__init__(logger, extra) + + def process(self, msg, kwargs): + if kwargs == {}: + return (msg, kwargs) + extra = kwargs.get("extra", {}) + extra.update({"es": kwargs.pop("es", True)}) + kwargs["extra"] = extra + return (msg, kwargs) + +logger = logging.getLogger(LOGGER_NAME) +logger.setLevel(logging.DEBUG) + +ch = logging.StreamHandler() +ch.setLevel(logging.WARNING) + +eh = ESHandler(host=esHost, port=esPort) +eh.setLevel(logging.DEBUG) + +formatter = logging.Formatter('%(asctime)s %(levelname)8s | %(message)s') +logger.addHandler(ch) +logger.addHandler(eh) +logger = ElasticFieldParameterAdapter(logger) + + diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..ef9b2cd --- /dev/null +++ b/utils.py @@ -0,0 +1,23 @@ +#!/bin/usr/python3 +import os +import yaml +import pytest + +def loadYaml(filePath): + with open(filePath, "r") as stream: + try: + return yaml.safe_load(stream) + except yaml.YAMLError as exception: + print('Error: {} is unparsable'.format(filePath)) + print(exception) + +def getConfig(): + pwd = os.path.dirname(os.path.abspath(__file__)) + path = os.path.join(pwd, 'config.yaml') + + if not os.path.isfile(path): + print('Please fill out and rename config file. Check README for more info.') + exit(0) + + return loadYaml(path) +