Last active
June 7, 2018 11:38
-
-
Save stemid/cbf506007a0b041ee3450c5505598bc2 to your computer and use it in GitHub Desktop.
Boilerplate logging class I use in most my applications
This file contains 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
# AppLogger specific config. | |
[logging] | |
log_format = %(asctime)s %(name)s[%(process)s] %(levelname)s: %(message)s | |
log_debug = True | |
log_level = INFO | |
# Handler can be one of file, stdout or syslog | |
log_handler = stdout | |
# Can use this to log directly to another server if need be | |
syslog_address = /dev/log | |
syslog_port = 514 | |
# For file handler, 20MB file size limit | |
log_max_bytes = 20971520 | |
log_max_copies = 5 | |
log_file = ./restapi.log |
This file contains 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
# This has served me well now for half a dozen different microservices | |
# and applications so it's time to put it up on Gist so I never lose it. | |
# Init like this; | |
# al = AppLogger('my-app', config) | |
# log = al.logger | |
# log.info('hej') | |
# Where config is a ConfigParser instance and the config file needs a | |
# [logging] section that is described in the config_defaults dict below. | |
# | |
# by Stefan Midjich <swehack at gmail dot com> | |
import sys | |
from logging import StreamHandler | |
from logging import Formatter, getLogger, getLevelName, DEBUG, WARN, INFO | |
from logging.handlers import SysLogHandler, RotatingFileHandler | |
# Mostly for documentation purposes | |
config_defaults = { | |
'log_format': '%(asctime)s %(name)s[%(process)s] %(levelname)s: %(message)s', | |
'log_debug': True, | |
'log_level': 'INFO', | |
# or file, or syslog | |
'log_handler': 'stdout', | |
# Can be remote server address | |
'syslog_address': '/dev/log', | |
'syslog_port': 514, | |
# 20MB | |
'log_max_bytes': 20971520, | |
'log_max_copies': 5, | |
'log_file': './default.log' | |
} | |
class AppLogger(object): | |
def __init__(self, name, config): | |
"""This initializes with a RawConfigParser object to get most of its | |
default settings. | |
""" | |
formatter = Formatter(config.get('logging', 'log_format')) | |
self.logger = getLogger(name) | |
if config.get('logging', 'log_handler') == 'syslog': | |
syslog_address = config.get('logging', 'syslog_address') | |
default_facility = SysLogHandler.LOG_LOCAL0 | |
if syslog_address.startswith('/'): | |
h = SysLogHandler( | |
address=syslog_address, | |
facility=default_facility | |
) | |
else: | |
h = SysLogHandler( | |
address=( | |
config.get('logging', 'syslog_address'), | |
config.get('logging', 'syslog_port') | |
), | |
facility=default_facility | |
) | |
elif config.get('logging', 'log_handler') == 'file': | |
h = RotatingFileHandler( | |
config.get('logging', 'log_file'), | |
maxBytes=config.getint('logging', 'log_max_bytes'), | |
backupCount=config.getint('logging', 'log_max_copies') | |
) | |
else: | |
h = StreamHandler(stream=sys.stdout) | |
h.setFormatter(formatter) | |
self.logger.addHandler(h) | |
try: | |
log_level = getLevelName( | |
config.get('logging', 'log_level').toupper() | |
) | |
except: | |
log_level = DEBUG | |
pass | |
self.handler = h | |
self.logger.setLevel(log_level) | |
def apply_handler(self, logger_name): | |
""" | |
Some frameworks init their own loggers, like tornado for example. | |
So use this to apply your handler to their loggers by specifying the | |
logger name. | |
""" | |
logger = getLogger(logger_name) | |
logger.addHandler(self.handler) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment