import contextlib
import warnings
import logging
import logging.handlers
lfmt = '[%(asctime)s][%(processName)s][%(threadName)s][%(levelname)-5s]: %(message)s'
dfmt = "%Y-%m-%d %H:%M:%S"
logging.basicConfig(level=logging.ERROR, format=lfmt, datefmt=dfmt)
logging.addLevelName(logging.CRITICAL, 'FATAL')
logging.addLevelName(logging.WARNING, 'WARN')
logging.getLogger('requests').setLevel(logging.ERROR)
logging.getLogger('urllib3').setLevel(logging.ERROR)
[docs]def set_level(level):
logging.getLogger().setLevel(level)
[docs]def set_debug():
set_level(logging.DEBUG)
[docs]def set_error():
set_level(logging.ERROR)
[docs]def set_info():
set_level(logging.INFO)
# noinspection PyUnusedLocal
[docs]@contextlib.contextmanager
def capture(capture_warnings=True, fail=False):
"""
Log exceptions and warnings.
"""
default_warning_format = warnings.formatwarning
try:
if capture_warnings:
warnings.formatwarning = custom_warning_format
logging.captureWarnings(True)
try:
yield
except Exception as e:
logging.exception('caught unhandled excetion')
if fail:
if not isinstance(e, Warning):
raise RuntimeError('application failure')
finally:
if capture_warnings:
warnings.formatwarning = default_warning_format
logging.captureWarnings(False)
[docs]class LoggingObject(object):
"""
Inherit from this to get a bunch of logging functions as class methods.
"""
def __init__(self):
self._init_notify()
def _init_notify(self):
self.debug('init')
[docs] def debug(self, msg, *args, **kwargs):
logging.debug(self._preprocess(msg), *args, **kwargs)
[docs] def error(self, msg, *args, **kwargs):
logging.error(self._preprocess(msg), *args, **kwargs)
[docs] def fatal(self, msg, *args, **kwargs):
logging.fatal(self._preprocess(msg), *args, **kwargs)
exit(-1)
[docs] def info(self, msg, *args, **kwargs):
logging.info(self._preprocess(msg), *args, **kwargs)
[docs] def exception(self, msg, *args, **kwargs):
logging.exception(self._preprocess(msg), *args, **kwargs)
[docs] def log(self, level, msg, *args, **kwargs):
logging.log(level, self._preprocess(msg), *args, **kwargs)
def _preprocess(self, msg):
return '{}: {}'.format(repr(self), msg)
[docs] @contextlib.contextmanager
def capture(self, **kwargs):
try:
with capture(**kwargs):
yield
finally:
pass
[docs]def add_rotating_file_handler(level=logging.DEBUG, fname='app.log',
logger=None, fmt=lfmt, **kwargs):
"""
Create rotating file handler and add it to logging.
:param level: logging level
:param fname: name of file
:param logger: logger instance
:param fmt: format
"""
_kwargs = dict(maxBytes=(1048576 * 5), backupCount=5)
_kwargs.update(**kwargs)
handler = logging.handlers.RotatingFileHandler(fname, **kwargs)
handler.setLevel(level)
formatter = logging.Formatter(fmt)
handler.setFormatter(formatter)
if isinstance(logger, str):
logger = logging.getLogger(logger)
elif logger is None:
logger = logging.getLogger()
logger.addHandler(handler)
return logger
[docs]def basic_config(verbose=False, silent=False, fname=None):
"""
Setup logging.
"""
set_info()
if verbose:
set_debug()
if silent:
set_error()
if fname:
add_rotating_file_handler(fname=fname)
if __name__ == '__main__':
pass