This commit is contained in:
ericrdunham 2021-09-29 15:03:36 +05:30 committed by GitHub
commit d5fa5fa95d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 21 deletions

3
RELEASE.md Normal file
View file

@ -0,0 +1,3 @@
Release type: patch
Address an issue where `--fatal=warnings|errors` would not honor entries in the `LOG_FILTER` setting.

View file

@ -149,24 +149,9 @@ class LimitLogger(logging.Logger):
self.addFilter(LimitLogger.limit_filter) self.addFilter(LimitLogger.limit_filter)
class FatalLogger(LimitLogger): logging.setLoggerClass(LimitLogger)
warnings_fatal = False
errors_fatal = False
def warning(self, *args, **kwargs):
super().warning(*args, **kwargs)
if FatalLogger.warnings_fatal:
raise RuntimeError('Warning encountered')
def error(self, *args, **kwargs):
super().error(*args, **kwargs)
if FatalLogger.errors_fatal:
raise RuntimeError('Error encountered')
logging.setLoggerClass(FatalLogger)
# force root logger to be of our preferred class # force root logger to be of our preferred class
logging.getLogger().__class__ = FatalLogger logging.getLogger().__class__ = LimitLogger
def supports_color(): def supports_color():
@ -194,11 +179,13 @@ def get_formatter():
return TextFormatter() return TextFormatter()
class FatalHandler(logging.Handler):
def emit(self, record):
sys.exit(1)
def init(level=None, fatal='', handler=logging.StreamHandler(), name=None, def init(level=None, fatal='', handler=logging.StreamHandler(), name=None,
logs_dedup_min_level=None): logs_dedup_min_level=None):
FatalLogger.warnings_fatal = fatal.startswith('warning')
FatalLogger.errors_fatal = bool(fatal)
logger = logging.getLogger(name) logger = logging.getLogger(name)
handler.setFormatter(get_formatter()) handler.setFormatter(get_formatter())
@ -209,6 +196,11 @@ def init(level=None, fatal='', handler=logging.StreamHandler(), name=None,
if logs_dedup_min_level: if logs_dedup_min_level:
LimitFilter.LOGS_DEDUP_MIN_LEVEL = logs_dedup_min_level LimitFilter.LOGS_DEDUP_MIN_LEVEL = logs_dedup_min_level
if fatal.startswith('warning'):
logger.addHandler(FatalHandler(level=logging.WARNING))
if fatal:
logger.addHandler(FatalHandler(level=logging.ERROR))
def log_warnings(): def log_warnings():
import warnings import warnings

View file

@ -163,7 +163,7 @@ DEFAULT_CONFIG = {
'WRITE_SELECTED': [], 'WRITE_SELECTED': [],
'FORMATTED_FIELDS': ['summary'], 'FORMATTED_FIELDS': ['summary'],
'PORT': 8000, 'PORT': 8000,
'BIND': '127.0.0.1', 'BIND': '127.0.0.1'
} }
PYGMENTS_RST_OPTIONS = None PYGMENTS_RST_OPTIONS = None

View file

@ -2,6 +2,7 @@ import logging
import unittest import unittest
from collections import defaultdict from collections import defaultdict
from contextlib import contextmanager from contextlib import contextmanager
from unittest import mock
from pelican import log from pelican import log
from pelican.tests.support import LogCountHandler from pelican.tests.support import LogCountHandler
@ -130,3 +131,48 @@ class TestLog(unittest.TestCase):
self.assertEqual( self.assertEqual(
self.handler.count_logs('Another log \\d', logging.WARNING), self.handler.count_logs('Another log \\d', logging.WARNING),
0) 0)
@mock.patch.object(log, 'sys')
class TestLogInit(unittest.TestCase):
def init(self, fatal, name):
logger = logging.getLogger(name)
log.init(fatal=fatal, name=name)
return logger
def test_fatal_warnings(self, sys):
logger = self.init('warnings', 'test_fatal_warnings')
logger.warning('foo')
logger.error('bar')
sys.exit.assert_called_with(1)
def test_fatal_errors(self, sys):
logger = self.init('errors', 'test_fatal_errors')
logger.warning('foo')
logger.error('bar')
sys.exit.assert_called_with(1)
def test_no_fatal(self, sys):
logger = self.init('', 'test_no_fatal')
logger.warning('foo')
logger.error('bar')
sys.exit.assert_not_called()
def test_fatal_warnings_log_filter(self, sys):
limit_filter = log.LimitFilter()
limit_filter._ignore = {(logging.WARNING, 'foo')}
lf = mock.PropertyMock(return_value=limit_filter)
with mock.patch('pelican.log.LimitLogger.limit_filter', new=lf):
logger = self.init('warnings', 'test_fatal_warnings_log_filter')
logger.warning('foo')
sys.exit.assert_not_called()
def test_fatal_errors_log_filter(self, sys):
limit_filter = log.LimitFilter()
limit_filter.LOGS_DEDUP_MIN_LEVEL = logging.CRITICAL
limit_filter._ignore = {(logging.ERROR, 'bar')}
lf = mock.PropertyMock(return_value=limit_filter)
with mock.patch('pelican.log.LimitLogger.limit_filter', new=lf):
logger = self.init('errors', 'test_fatal_errors_log_filter')
logger.error('bar')
sys.exit.assert_not_called()