diff options
-rw-r--r-- | qutebrowser/app.py | 2 | ||||
-rw-r--r-- | qutebrowser/config/configdata.yml | 23 | ||||
-rw-r--r-- | qutebrowser/qutebrowser.py | 2 | ||||
-rw-r--r-- | qutebrowser/utils/log.py | 26 | ||||
-rw-r--r-- | tests/unit/utils/test_log.py | 24 |
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.""" |