diff --git a/CHANGELOG.md b/CHANGELOG.md index 820b77cf..e80bc5f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ Bugs: -- None +- `[ext.logging]` Support `logging.propagate` to avoid duplicate log entries. + - [Issue #310](https://github.com/datafolklabs/cement/issues/310) Features: diff --git a/cement/ext/ext_logging.py b/cement/ext/ext_logging.py index 37e6b034..6462de89 100644 --- a/cement/ext/ext_logging.py +++ b/cement/ext/ext_logging.py @@ -93,6 +93,18 @@ class LoggingLogHandler(log.LogHandler): #: The help description for the log level argument log_level_argument_help = 'logging level' + #: Whether or not to propagate logs up to parents. Likely should + #: always be ``False``, but is here in the off chance this breaks + #: something. Setting to ``False`` resolves situation where duplicate + #: logs appears when using other libraries who logged to the root + #: logger. + #: + #: Note, if attempting to use PyTest ``caplog`` fixture, this may need + #: to be set to ``True``. + #: + #: See: ``tests.ext.test_ext_colorlog.test_colorlog``. + propagate = False + levels = ['INFO', 'WARNING', 'ERROR', 'DEBUG', 'FATAL', 'CRITICAL'] def __init__(self, *args, **kw): @@ -113,6 +125,7 @@ class LoggingLogHandler(log.LogHandler): level = self.app.config.get(self._meta.config_section, 'level') self.set_level(level) + self.backend.propagate = self._meta.propagate LOG.debug("logging initialized for '%s' using %s" % (self._meta.namespace, self.__class__.__name__)) @@ -158,6 +171,10 @@ class LoggingLogHandler(log.LogHandler): def clear_loggers(self, namespace): """Clear any previously configured loggers for ``namespace``.""" + # clear root loggers + # logging.getLogger().handlers = [] + # logging.l + for i in logging.getLogger("cement:app:%s" % namespace).handlers: logging.getLogger("cement:app:%s" % namespace).removeHandler(i) diff --git a/tests/ext/test_ext_colorlog.py b/tests/ext/test_ext_colorlog.py index 9fe04c94..83eff96e 100644 --- a/tests/ext/test_ext_colorlog.py +++ b/tests/ext/test_ext_colorlog.py @@ -22,7 +22,9 @@ class ColorlogApp(TestApp): def test_colorlog(caplog): - with ColorlogApp() as app: + META = init_defaults('log.colorlog') + META['log.colorlog']['propagate'] = True + with ColorlogApp(meta_defaults=META) as app: app.run() app.log.info('this is an info message') app.log.warning('this is a warning message')