Support logging.propagate to avoid duplicate log entries.

- Resolves Issue #310
This commit is contained in:
BJ Dierkes 2023-12-26 18:52:45 -06:00
parent e88ab3d716
commit 03b0dd339b
3 changed files with 22 additions and 2 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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')