Created
May 19, 2020 11:39
-
-
Save mattwang44/b0a41435ce59a90f6f259da59f04c12d to your computer and use it in GitHub Desktop.
Simple python structured logger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
import json | |
# modified from https://docs.python.org/3/howto/logging-cookbook.html#implementing-structured-logging | |
class StructuredLogger: | |
''' The wrapper of logger that handles structurizing logs | |
and passing logs to the root logger ''' | |
class Structurize: | |
''' Converter for structured log ''' | |
def __init__(self, message, level, **kwargs): | |
self.message = message | |
self.level = level | |
self.kwargs = kwargs | |
def __str__(self): | |
log = { | |
'msg': self.message, | |
'level': self.level, | |
**self.kwargs | |
} | |
return json.dumps(log) | |
def __init__(self): | |
self.logger = logging.getLogger() | |
# delete the default handlers (if needed) | |
if self.logger.handlers: | |
for handler in self.logger.handlers: | |
self.logger.removeHandler(handler) | |
logging.basicConfig(format='%(message)s', level=logging.INFO) | |
def __getattr__(self, method): | |
if method in ['debug', 'info', 'warning', 'error', 'critical']: | |
def fn(message, exc_info=False, **kwargs): | |
f = getattr(self.logger, method) | |
level = method | |
f(self.Structurize(message, level, **kwargs), exc_info=exc_info) | |
return fn | |
else: | |
raise AttributeError | |
if __name__ == '__main__': | |
logger = StructuredLogger() | |
logger.info('test message 1') | |
# {"msg": "test message 1", "level": "info"} | |
logger.warning('test message 2', foo='bar', foo1='bar1') | |
# {"msg": "test message 2", "level": "warning", "foo": "bar", "foo1": "bar1"} | |
try: | |
1 / 0 | |
except Exception as err: | |
logger.error('test message 3', foo='bar', err=str(err)) | |
# {"msg": "test message 3", "level": "error", "foo": "bar", "err": "divisionby zero"} | |
try: | |
1 / 0 | |
except: | |
logger.error('test message 4', foo='bar', exc_info=True) | |
''' | |
{"msg": "test message 4", "level": "error", "foo": "bar"} | |
Traceback (most recent call last): | |
File "log.py", line 70, in <module> | |
1 / 0 | |
ZeroDivisionError: division by zero | |
''' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment