Simplify custom logging classes
No need to use meta programming to support dedent of text blocks on message emission for simpler log messages. Change-Id: Icacb1c2f422cb6035b6b93a21c90b8896f0ac79c
This commit is contained in:
@@ -24,12 +24,9 @@ functions for verbose/quiet CLI args to retreive the appropriate level
|
|||||||
for logging output to the console.
|
for logging output to the console.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from functools import wraps
|
|
||||||
import logging
|
import logging
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
# Add new NOTICE logging level
|
# Add new NOTICE logging level
|
||||||
NOTICE = (logging.INFO + logging.WARN) // 2
|
NOTICE = (logging.INFO + logging.WARN) // 2
|
||||||
@@ -37,17 +34,6 @@ logging.NOTICE = NOTICE
|
|||||||
logging.addLevelName(NOTICE, "NOTICE")
|
logging.addLevelName(NOTICE, "NOTICE")
|
||||||
|
|
||||||
|
|
||||||
def notice(self, msg, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Supports same arguments as default methods available from
|
|
||||||
logging.Logger class
|
|
||||||
"""
|
|
||||||
if self.isEnabledFor(NOTICE):
|
|
||||||
self._log(NOTICE, msg, args, **kwargs)
|
|
||||||
|
|
||||||
logging.Logger.notice = notice
|
|
||||||
|
|
||||||
|
|
||||||
def get_logger(name=None):
|
def get_logger(name=None):
|
||||||
"""
|
"""
|
||||||
Wrapper for standard logging.getLogger that ensures all loggers in this
|
Wrapper for standard logging.getLogger that ensures all loggers in this
|
||||||
@@ -96,53 +82,21 @@ class LevelFilterIgnoreBelow(logging.Filter):
|
|||||||
return record.levelno >= self.level
|
return record.levelno >= self.level
|
||||||
|
|
||||||
|
|
||||||
class DedentLoggerMeta(type):
|
|
||||||
"""
|
|
||||||
Meta class to wrap all level functions in logging interface with dedent
|
|
||||||
|
|
||||||
Classes created from this should be derived from the logging.Logger class
|
|
||||||
as otherwise they will not contain the correct methods to be wrapped and
|
|
||||||
trying to pass them as the default class to create Loggers from will fail.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __new__(cls, name, bases, dict):
|
|
||||||
# provide a more intelligent error instead of waiting for
|
|
||||||
# setattr/getattr adding of a wrapper function to fail
|
|
||||||
if logging.Logger not in bases:
|
|
||||||
raise TypeError("%s not derived from logging.Logger" % name)
|
|
||||||
|
|
||||||
obj = super(DedentLoggerMeta, cls).__new__(cls, name, bases, dict)
|
|
||||||
for levelalias in _levels:
|
|
||||||
level = levelalias[0]
|
|
||||||
aliases = levelalias[1:]
|
|
||||||
setattr(obj, level, cls.wrap()(getattr(obj, level)))
|
|
||||||
for alias in aliases:
|
|
||||||
setattr(obj, alias, getattr(obj, level))
|
|
||||||
setattr(obj, 'log', cls.wrap(True)(getattr(obj, 'log')))
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def wrap(with_level=False):
|
|
||||||
def dedentlog(func):
|
|
||||||
if with_level:
|
|
||||||
def _dedent_log(self, level, msg, *args, **kwargs):
|
|
||||||
dedent = kwargs.pop('dedent', True)
|
|
||||||
if dedent:
|
|
||||||
msg = textwrap.dedent(msg.lstrip('\n'))
|
|
||||||
func(self, level, msg, *args, **kwargs)
|
|
||||||
else:
|
|
||||||
def _dedent_log(self, msg, *args, **kwargs):
|
|
||||||
dedent = kwargs.pop('dedent', True)
|
|
||||||
if dedent:
|
|
||||||
msg = textwrap.dedent(msg.lstrip('\n'))
|
|
||||||
func(self, msg, *args, **kwargs)
|
|
||||||
return wraps(func)(_dedent_log)
|
|
||||||
return dedentlog
|
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(DedentLoggerMeta)
|
|
||||||
class DedentLogger(logging.Logger):
|
class DedentLogger(logging.Logger):
|
||||||
pass
|
|
||||||
|
def _log(self, level, msg, args, **kwargs):
|
||||||
|
dedent = kwargs.pop('dedent', True)
|
||||||
|
if dedent:
|
||||||
|
msg = textwrap.dedent(msg.lstrip('\n'))
|
||||||
|
super(DedentLogger, self)._log(level, msg, args, **kwargs)
|
||||||
|
|
||||||
|
def notice(self, msg, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Supports same arguments as default methods available from
|
||||||
|
logging.Logger class
|
||||||
|
"""
|
||||||
|
if self.isEnabledFor(NOTICE):
|
||||||
|
self._log(NOTICE, msg, args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# override default logger class for everything that imports this module
|
# override default logger class for everything that imports this module
|
||||||
@@ -152,10 +106,10 @@ logging.setLoggerClass(DedentLogger)
|
|||||||
class LogDedentMixin(object):
|
class LogDedentMixin(object):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.__log = get_logger('%s.%s' % (__name__, self.__class__.__name__))
|
self._log = get_logger('%s.%s' % (__name__, self.__class__.__name__))
|
||||||
|
|
||||||
super(LogDedentMixin, self).__init__(*args, **kwargs)
|
super(LogDedentMixin, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def log(self):
|
def log(self):
|
||||||
return self.__log
|
return self._log
|
||||||
|
Reference in New Issue
Block a user