diff --git a/src/blueapi/cli/cli.py b/src/blueapi/cli/cli.py index 7bafa831f..86a2cd561 100644 --- a/src/blueapi/cli/cli.py +++ b/src/blueapi/cli/cli.py @@ -83,8 +83,24 @@ def is_str_dict(val: Any) -> TypeGuard[TaskParameters]: @click.option( "-c", "--config", type=Path, help="Path to configuration YAML file", multiple=True ) +@click.option( + "-v", + "--verbose", + "log_level", + flag_value="DEBUG", + help="Include DEBUG level logging output", +) +@click.option( + "-q", + "--quiet", + "log_level", + flag_value="ERROR", + help="Reduce logging noise to only show errors", +) @click.pass_context -def main(ctx: click.Context, config: tuple[Path, ...]) -> None: +def main( + ctx: click.Context, config: tuple[Path, ...], log_level: str | None = None +) -> None: # if no command is supplied, run with the options passed # Set umask to DLS standard @@ -96,6 +112,9 @@ def main(ctx: click.Context, config: tuple[Path, ...]) -> None: except FileNotFoundError as fnfe: raise ClickException(f"Config file not found: {fnfe.filename}") from fnfe + if log_level: + config_loader.use_values({"logging": {"level": log_level}}) + loaded_config: ApplicationConfig = config_loader.load() set_up_logging(loaded_config.logging) diff --git a/tests/unit_tests/cli/test_cli.py b/tests/unit_tests/cli/test_cli.py index 93a01d0c9..35bc830ae 100644 --- a/tests/unit_tests/cli/test_cli.py +++ b/tests/unit_tests/cli/test_cli.py @@ -1384,3 +1384,14 @@ def test_config_schema( def test_task_parameter_type(value, result): t = ParametersType() assert t.convert(value, None, None) == result + + +@pytest.mark.parametrize( + "flag,level", + [("--verbose", "DEBUG"), ("--quiet", "ERROR"), ("-v", "DEBUG"), ("-q", "ERROR")], +) +def test_log_level_override(flag: str, level: str, runner: CliRunner): + with patch("blueapi.log.logging") as mock_log: + runner.invoke(main, [flag]) + mock_log.getLogger().setLevel.assert_called_once_with(level) + mock_log.StreamHandler().setLevel.assert_called_once_with(level)