Skip to content

Instantly share code, notes, and snippets.

@mattwang44
Created May 19, 2020 11:39
Show Gist options
  • Save mattwang44/b0a41435ce59a90f6f259da59f04c12d to your computer and use it in GitHub Desktop.
Save mattwang44/b0a41435ce59a90f6f259da59f04c12d to your computer and use it in GitHub Desktop.
Simple python structured logger
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