diff --git a/cli/planoai/main.py b/cli/planoai/main.py index 9157373c..a11945b7 100644 --- a/cli/planoai/main.py +++ b/cli/planoai/main.py @@ -16,6 +16,7 @@ from planoai.utils import ( get_llm_provider_access_keys, has_ingress_listener, load_env_file_to_dict, + set_log_level, stream_access_logs, find_config_file, find_repo_root, @@ -67,6 +68,8 @@ def get_version(): @click.option("--version", is_flag=True, help="Show the plano cli version and exit.") @click.pass_context def main(ctx, version): + # Set log level from LOG_LEVEL env var only + set_log_level(os.environ.get("LOG_LEVEL", "info")) if version: click.echo(f"plano cli version: {get_version()}") ctx.exit() @@ -192,6 +195,10 @@ def up(file, path, foreground): else: env_stage[access_key] = env_file_dict[access_key] + # Pass log level to the Docker container — supervisord uses LOG_LEVEL + # to set RUST_LOG (brightstaff) and envoy component log levels + env_stage["LOG_LEVEL"] = os.environ.get("LOG_LEVEL", "info") + env.update(env_stage) start_arch(arch_config_file, env, foreground=foreground) diff --git a/cli/planoai/utils.py b/cli/planoai/utils.py index ea9b8dbd..d55774f4 100644 --- a/cli/planoai/utils.py +++ b/cli/planoai/utils.py @@ -7,15 +7,34 @@ import logging from planoai.consts import PLANO_DOCKER_NAME +# Standard env var for log level across all Plano components +LOG_LEVEL_ENV = "LOG_LEVEL" + +_env_log_level = os.environ.get(LOG_LEVEL_ENV, "info").upper() +_log_level = getattr(logging, _env_log_level, logging.INFO) + logging.basicConfig( - level=logging.INFO, + level=_log_level, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) +def set_log_level(level: str): + """Set the log level for all loggers. Accepts: debug, info, warn, error.""" + global _log_level + numeric_level = getattr(logging, level.upper(), None) + if numeric_level is None: + raise ValueError(f"Invalid log level: {level}") + _log_level = numeric_level + logging.getLogger().setLevel(_log_level) + # Update all existing planoai loggers + for name in logging.Logger.manager.loggerDict: + logging.getLogger(name).setLevel(_log_level) + + def getLogger(name="cli"): logger = logging.getLogger(name) - logger.setLevel(logging.INFO) + logger.setLevel(_log_level) return logger diff --git a/config/supervisord.conf b/config/supervisord.conf index 35923974..a8762ef5 100644 --- a/config/supervisord.conf +++ b/config/supervisord.conf @@ -4,7 +4,7 @@ nodaemon=true [program:brightstaff] command=sh -c "\ envsubst < /app/arch_config_rendered.yaml > /app/arch_config_rendered.env_sub.yaml && \ - RUST_LOG=info \ + RUST_LOG=${LOG_LEVEL:-info} \ ARCH_CONFIG_PATH_RENDERED=/app/arch_config_rendered.env_sub.yaml \ /app/brightstaff 2>&1 | \ tee /var/log/brightstaff.log | \ @@ -18,8 +18,8 @@ stderr_logfile_maxbytes=0 command=/bin/sh -c "\ uv run python -m planoai.config_generator && \ envsubst < /etc/envoy/envoy.yaml > /etc/envoy.env_sub.yaml && \ - envoy -c /etc/envoy.env_sub.yaml \ - --component-log-level wasm:info \ + envoy -c /etc/envoy.env_sub.yaml \ + --component-log-level wasm:${LOG_LEVEL:-info} \ --log-format '[%%Y-%%m-%%d %%T.%%e][%%l] %%v' 2>&1 | \ tee /var/log/envoy.log | \ while IFS= read -r line; do echo '[plano_logs]' \"$line\"; done"