summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Roden-Corrent <ryan@rcorre.net>2020-05-17 07:01:06 -0400
committerRyan Roden-Corrent <ryan@rcorre.net>2020-05-17 17:37:45 -0400
commit5a0497a087f9fda0883930d1beda537a540ba73b (patch)
treec8d22da67bdde2722f91cc9bf8f7efdfcd963ca4
parent305e7c96d5e2fdb3b248b27dfb21042fb2b7e0b8 (diff)
downloadqutebrowser-5a0497a087f9fda0883930d1beda537a540ba73b.tar.gz
qutebrowser-5a0497a087f9fda0883930d1beda537a540ba73b.zip
Add loglevel config settings.
Log levels can now be configured in config.py by setting loggin.level.console (for stdout/stderr) and logging.level.ram (for :messages). This is of interest for users who would like password-manager integration that uses `fake-key` to send sensitive strings to websites. The default 'debug' ram logging would store various logs containing the sensitive data. Previously the loglevel was only configurable through CLI flags, and those only affected the console loglevel. We felt a config value would be nicer than just adding another flag for RAM loglevel, requiring you to create an alias for qutebrowser and ensure _that_ alias gets used anywhere qutebrowser might be invoked. Logging is initialized before the config is loaded, so configuration-set loglevels have to be loaded in a second, later stage. However, this stage will only set the console loglevel if it wasn't set on the CLI, as a CLI flag feels like a more explicit action that should override a config. Fixes #5286.
-rw-r--r--qutebrowser/app.py2
-rw-r--r--qutebrowser/config/configdata.yml23
-rw-r--r--qutebrowser/qutebrowser.py2
-rw-r--r--qutebrowser/utils/log.py26
-rw-r--r--tests/unit/utils/test_log.py24
5 files changed, 75 insertions, 2 deletions
diff --git a/qutebrowser/app.py b/qutebrowser/app.py
index 6d01e0ddd..b89fa4b37 100644
--- a/qutebrowser/app.py
+++ b/qutebrowser/app.py
@@ -379,6 +379,8 @@ def _init_modules(*, args):
Args:
args: The argparse namespace.
"""
+ log.init.debug("Initializing logging from config...")
+ log.init_from_config(config.val)
log.init.debug("Initializing save manager...")
save_manager = savemanager.SaveManager(q_app)
objreg.register('save-manager', save_manager)
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 393ae8ac0..98ec76fd7 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -3194,3 +3194,26 @@ bindings.commands:
* register: Entered when qutebrowser is waiting for a register name/key for
commands like `:set-mark`.
+
+## logging
+
+logging.level.ram:
+ default: null
+ type:
+ name: String
+ none_ok: true
+ # levels match those in qutebrowser/utils/log.py
+ valid_values: ['VDEBUG', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
+ desc:
+ Level for in-memory logs.
+
+logging.level.console:
+ default: null
+ type:
+ name: String
+ none_ok: true
+ # levels match those in qutebrowser/utils/log.py
+ valid_values: ['VDEBUG', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
+ desc: >-
+ Level for console (stdout/stderr) logs.
+ Ignored if the --loglevel or --debug CLI flags are used.
diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py
index 0ffdb5567..3369c1ebe 100644
--- a/qutebrowser/qutebrowser.py
+++ b/qutebrowser/qutebrowser.py
@@ -96,7 +96,7 @@ def get_argparser():
debug = parser.add_argument_group('debug arguments')
debug.add_argument('-l', '--loglevel', dest='loglevel',
- help="Set loglevel", default='info',
+ help="Override the configured console loglevel",
choices=['critical', 'error', 'warning', 'info',
'debug', 'vdebug'])
debug.add_argument('--logfilter', type=logfilter_error,
diff --git a/qutebrowser/utils/log.py b/qutebrowser/utils/log.py
index 2718f10ba..6cf204b5d 100644
--- a/qutebrowser/utils/log.py
+++ b/qutebrowser/utils/log.py
@@ -176,7 +176,7 @@ def stub(suffix: str = '') -> None:
def init_log(args: argparse.Namespace) -> None:
"""Init loggers based on the argparse namespace passed."""
- level = args.loglevel.upper()
+ level = (args.loglevel or "info").upper()
try:
numeric_level = getattr(logging, level)
except AttributeError:
@@ -526,6 +526,30 @@ def hide_qt_warning(pattern: str, logger: str = 'qt') -> typing.Iterator[None]:
logger_obj.removeFilter(log_filter)
+def init_from_config(conf: typing.Any) -> None:
+ """Initialize logging settings from the config.
+
+ init_log is called before the config module is initialized, so config-based
+ initialization cannot be performed there.
+
+ Args:
+ conf: The global ConfigContainer.
+ This is passed rather than accessed via the module to avoid a
+ cyclic import.
+ """
+ ramlevel = conf.logging.level.ram
+ consolelevel = conf.logging.level.console
+ if ramlevel and ram_handler:
+ init.info("Configuring RAM loglevel to %s", ramlevel)
+ ram_handler.setLevel(LOG_LEVELS[ramlevel])
+ if consolelevel and console_handler:
+ if _args and _args.loglevel:
+ init.info("--loglevel flag overrides logging.level.console")
+ else:
+ init.info("Configuring console loglevel to %s", consolelevel)
+ console_handler.setLevel(LOG_LEVELS[consolelevel])
+
+
class QtWarningFilter(logging.Filter):
"""Filter to filter Qt warnings.
diff --git a/tests/unit/utils/test_log.py b/tests/unit/utils/test_log.py
index a74d81600..45543a136 100644
--- a/tests/unit/utils/test_log.py
+++ b/tests/unit/utils/test_log.py
@@ -255,6 +255,30 @@ class TestInitLog:
warnings.warn("test warning", PendingDeprecationWarning)
+@pytest.mark.parametrize(
+ 'console_cli,console_conf,console_expected,ram_conf,ram_expected',
+ [
+ (None, None, logging.INFO, None, logging.NOTSET),
+ (None, None, logging.INFO, 'CRITICAL', logging.CRITICAL),
+ (None, 'WARNING', logging.WARNING, 'INFO', logging.INFO),
+ ('INFO', 'WARNING', logging.INFO, 'VDEBUG', logging.VDEBUG),
+ ('WARNING', 'INFO', logging.WARNING, 'CRITICAL', logging.CRITICAL),
+ ])
+def test_init_from_config(mocker, console_cli, console_conf, console_expected,
+ ram_conf, ram_expected):
+ args = argparse.Namespace(debug=False, loglevel=console_cli, color=True,
+ loglines=10, logfilter="", force_color=False,
+ json_logging=False, debug_flags=set())
+ log.init_log(args)
+
+ conf = mocker.Mock()
+ conf.logging.level.ram = ram_conf
+ conf.logging.level.console = console_conf
+ log.init_from_config(conf)
+ assert log.ram_handler.level == ram_expected
+ assert log.console_handler.level == console_expected
+
+
class TestHideQtWarning:
"""Tests for hide_qt_warning/QtWarningFilter."""