Merge remote-tracking branch 'origin/pr/3973'

This commit is contained in:
Florian Bruhin 2018-06-11 12:34:18 +02:00
commit 2934f4a1ca
4 changed files with 62 additions and 24 deletions

View File

@ -198,8 +198,8 @@ There are some useful functions for debugging in the `qutebrowser.utils.debug`
module. module.
When starting qutebrowser with the `--debug` flag, you also get useful debug When starting qutebrowser with the `--debug` flag, you also get useful debug
logs. You can add +--logfilter _category[,category,...]_+ to restrict logging logs. You can add +--logfilter _[!]category[,category,...]_+ to restrict
to the given categories. logging to the given categories.
With `--debug` there are also some additional +debug-_*_+ commands available, With `--debug` there are also some additional +debug-_*_+ commands available,
for example `:debug-all-objects` and `:debug-all-widgets` which print a list of for example `:debug-all-objects` and `:debug-all-widgets` which print a list of

View File

@ -148,7 +148,7 @@ def logfilter_error(logfilter):
Args: Args:
logfilter: A comma separated list of logger names. logfilter: A comma separated list of logger names.
""" """
if set(logfilter.split(',')).issubset(log.LOGGER_NAMES): if set(logfilter.lstrip('!').split(',')).issubset(log.LOGGER_NAMES):
return logfilter return logfilter
else: else:
raise argparse.ArgumentTypeError( raise argparse.ArgumentTypeError(

View File

@ -182,9 +182,16 @@ def init_log(args):
root = logging.getLogger() root = logging.getLogger()
global console_filter global console_filter
if console is not None: if console is not None:
console_filter = LogFilter(None) if not args.logfilter:
if args.logfilter is not None: negate = False
console_filter.names = args.logfilter.split(',') names = None
elif args.logfilter.startswith('!'):
negate = True
names = args.logfilter[1:].split(',')
else:
negate = False
names = args.logfilter.split(',')
console_filter = LogFilter(names, negate)
console.addFilter(console_filter) console.addFilter(console_filter)
root.addHandler(console) root.addHandler(console)
if ram is not None: if ram is not None:
@ -498,12 +505,14 @@ class LogFilter(logging.Filter):
comma-separated list instead. comma-separated list instead.
Attributes: Attributes:
_names: A list of names that should be logged. names: A list of record names to filter.
negated: Wether names is a list of records to log or to suppress.
""" """
def __init__(self, names): def __init__(self, names, negate=False):
super().__init__() super().__init__()
self.names = names self.names = names
self.negated = negate
def filter(self, record): def filter(self, record):
"""Determine if the specified record is to be logged.""" """Determine if the specified record is to be logged."""
@ -514,12 +523,12 @@ class LogFilter(logging.Filter):
return True return True
for name in self.names: for name in self.names:
if record.name == name: if record.name == name:
return True return not self.negated
elif not record.name.startswith(name): elif not record.name.startswith(name):
continue continue
elif record.name[len(name)] == '.': elif record.name[len(name)] == '.':
return True return not self.negated
return False return self.negated
class RAMHandler(logging.Handler): class RAMHandler(logging.Handler):

View File

@ -116,24 +116,36 @@ class TestLogFilter:
return logger.makeRecord(name, level=level, fn=None, lno=0, msg="", return logger.makeRecord(name, level=level, fn=None, lno=0, msg="",
args=None, exc_info=None) args=None, exc_info=None)
@pytest.mark.parametrize('filters, category, logged', [ @pytest.mark.parametrize('filters, negated, category, logged', [
# Filter letting all messages through # Filter letting all messages through
(None, 'eggs.bacon.spam', True), (None, False, 'eggs.bacon.spam', True),
(None, 'eggs', True), (None, False, 'eggs', True),
(None, True, 'ham', True),
# Matching records # Matching records
(['eggs', 'bacon'], 'eggs', True), (['eggs', 'bacon'], False, 'eggs', True),
(['eggs', 'bacon'], 'bacon', True), (['eggs', 'bacon'], False, 'bacon', True),
(['eggs.bacon'], 'eggs.bacon', True), (['eggs.bacon'], False, 'eggs.bacon', True),
# Non-matching records # Non-matching records
(['eggs', 'bacon'], 'spam', False), (['eggs', 'bacon'], False, 'spam', False),
(['eggs'], 'eggsauce', False), (['eggs'], False, 'eggsauce', False),
(['eggs.bacon'], 'eggs.baconstrips', False), (['eggs.bacon'], False, 'eggs.baconstrips', False),
# Child loggers # Child loggers
(['eggs.bacon', 'spam.ham'], 'eggs.bacon.spam', True), (['eggs.bacon', 'spam.ham'], False, 'eggs.bacon.spam', True),
(['eggs.bacon', 'spam.ham'], 'spam.ham.salami', True), (['eggs.bacon', 'spam.ham'], False, 'spam.ham.salami', True),
# Suppressed records
(['eggs', 'bacon'], True, 'eggs', False),
(['eggs', 'bacon'], True, 'bacon', False),
(['eggs.bacon'], True, 'eggs.bacon', False),
# Non-suppressed records
(['eggs', 'bacon'], True, 'spam', True),
(['eggs'], True, 'eggsauce', True),
(['eggs.bacon'], True, 'eggs.baconstrips', True),
]) ])
def test_logfilter(self, logger, filters, category, logged): def test_logfilter(self, logger, filters, negated, category, logged):
logfilter = log.LogFilter(filters) """
Check the multi-record filtering filterer filters multiple records.
"""
logfilter = log.LogFilter(filters, negated)
record = self._make_record(logger, category) record = self._make_record(logger, category)
assert logfilter.filter(record) == logged assert logfilter.filter(record) == logged
@ -204,6 +216,23 @@ class TestInitLog:
log.init_log(args) log.init_log(args)
sys.stderr = old_stderr sys.stderr = old_stderr
@pytest.mark.parametrize('logfilter, negated', [
('!one,two', True),
('one,two', False),
('one,!two', False),
(None, False),
])
def test_negation_parser(self, args, mocker, logfilter, negated):
"""Test parsing the --logfilter argument."""
filter_mock = mocker.patch('qutebrowser.utils.log.LogFilter',
autospec=True)
args.logfilter = logfilter
log.init_log(args)
expected_names = (logfilter.lstrip('!').split(',') if logfilter else
None)
assert filter_mock.called
assert filter_mock.call_args[0] == (expected_names, negated)
class TestHideQtWarning: class TestHideQtWarning: