diff --git a/changes/2698.fix.md b/changes/2698.fix.md new file mode 100644 index 0000000000..1b8977cabf --- /dev/null +++ b/changes/2698.fix.md @@ -0,0 +1 @@ +Add missing implementation of wsproxy and manager CLI's log-level customization options diff --git a/src/ai/backend/manager/cli/__main__.py b/src/ai/backend/manager/cli/__main__.py index b34e2d65f8..f5fd2dc37e 100644 --- a/src/ai/backend/manager/cli/__main__.py +++ b/src/ai/backend/manager/cli/__main__.py @@ -64,6 +64,8 @@ def main( Manager Administration CLI """ setproctitle("backend.ai: manager.cli") + if debug: + log_level = LogLevel.DEBUG ctx.obj = ctx.with_resource(CLIContext(config_path, log_level)) diff --git a/src/ai/backend/manager/cli/context.py b/src/ai/backend/manager/cli/context.py index 0ab08e6410..46bad1b52d 100644 --- a/src/ai/backend/manager/cli/context.py +++ b/src/ai/backend/manager/cli/context.py @@ -52,7 +52,13 @@ def __enter__(self) -> Self: # If we duplicate the local logging with it, the process termination may hang. click_ctx = click.get_current_context() if click_ctx.invoked_subcommand != "start-server": - logging_config = {} + logging_config = { + "level": self.log_level, + "pkg-ns": { + "": LogLevel.WARNING, + "ai.backend": self.log_level, + }, + } try: # Try getting the logging config but silently fallback to the default if not # present (e.g., when `mgr gql show` command used in CI without installation as diff --git a/src/ai/backend/wsproxy/cli/__main__.py b/src/ai/backend/wsproxy/cli/__main__.py index bca4e0bb01..583d1ab30e 100644 --- a/src/ai/backend/wsproxy/cli/__main__.py +++ b/src/ai/backend/wsproxy/cli/__main__.py @@ -1,6 +1,7 @@ import asyncio import importlib import json +import logging from pathlib import Path from typing import Any @@ -15,9 +16,30 @@ from ..config import ServerConfig, generate_example_json from ..openapi import generate_openapi from ..utils import ensure_json_serializable +from .context import CLIContext + +log = logging.getLogger(__spec__.name) # type: ignore[name-defined,union-attr] @click.group(invoke_without_command=False, context_settings={"help_option_names": ["-h", "--help"]}) +@click.option( + "-f", + "--config-path", + "--config", + type=click.Path( + file_okay=True, + dir_okay=False, + exists=True, + path_type=Path, + ), + default=None, + help="The config file path. (default: ./manager.conf and /etc/backend.ai/manager.conf)", +) +@click.option( + "--debug", + is_flag=True, + help="Set the logging level to DEBUG", +) @click.option( "--log-level", type=click.Choice([*LogLevel], case_sensitive=False), @@ -27,12 +49,17 @@ @click.pass_context def main( ctx: click.Context, - log_level: str, + config_path: Path, + log_level: LogLevel, + debug: bool, ) -> None: """ Backend.AI WSProxy CLI """ setproctitle("backend.ai: wsproxy.cli") + if debug: + log_level = LogLevel.DEBUG + ctx.obj = ctx.with_resource(CLIContext(config_path, log_level)) @main.command() diff --git a/src/ai/backend/wsproxy/cli/context.py b/src/ai/backend/wsproxy/cli/context.py index 213fdc1a2f..99663e36e9 100644 --- a/src/ai/backend/wsproxy/cli/context.py +++ b/src/ai/backend/wsproxy/cli/context.py @@ -31,7 +31,13 @@ def __enter__(self) -> Self: # If we duplicate the local logging with it, the process termination may hang. click_ctx = click.get_current_context() if click_ctx.invoked_subcommand != "start-server": - self._logger = LocalLogger({}) + self._logger = LocalLogger({ + "level": self.log_level, + "pkg-ns": { + "": LogLevel.WARNING, + "ai.backend": self.log_level, + }, + }) self._logger.__enter__() return self diff --git a/src/ai/backend/wsproxy/server.py b/src/ai/backend/wsproxy/server.py index d462d689d0..aa689fdf56 100644 --- a/src/ai/backend/wsproxy/server.py +++ b/src/ai/backend/wsproxy/server.py @@ -408,6 +408,11 @@ async def server_main_logwrapper( default=None, help=("The config file path. (default: ./wsproxy.toml and /etc/backend.ai/wsproxy.toml)"), ) +@click.option( + "--debug", + is_flag=True, + help="This option will soon change to --log-level TEXT option.", +) @click.option( "--log-level", type=click.Choice([*LogLevel], case_sensitive=False), @@ -415,11 +420,16 @@ async def server_main_logwrapper( help="Set the logging verbosity level", ) @click.pass_context -def main(ctx: click.Context, config_path: Path, log_level: LogLevel) -> None: +def main( + ctx: click.Context, + config_path: Path, + log_level: str, + debug: bool = False, +) -> None: """ Start the wsproxy service as a foreground process. """ - cfg = load_config(config_path, log_level) + cfg = load_config(config_path, LogLevel.DEBUG if debug else LogLevel[log_level]) if ctx.invoked_subcommand is None: cfg.wsproxy.pid_file.touch(exist_ok=True)