From f023e2e462453a8ebab8c1819794e12432d401ed Mon Sep 17 00:00:00 2001 From: Jvst Me Date: Wed, 6 Aug 2025 19:13:10 +0200 Subject: [PATCH] Fix configuring CLI logging on Python 3.9/3.10 Do not use `logging.getLevelNamesMapping` introduced in 3.11. No need to get the numeric levels at all - just set the configured named levels on the handlers and set DEBUG on the logger. This way, the logger allows all messages, but level filtering is then done by the handlers. --- src/dstack/_internal/cli/utils/common.py | 17 +++++------------ src/dstack/_internal/settings.py | 3 +++ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/dstack/_internal/cli/utils/common.py b/src/dstack/_internal/cli/utils/common.py index 72911584a4..543fea931a 100644 --- a/src/dstack/_internal/cli/utils/common.py +++ b/src/dstack/_internal/cli/utils/common.py @@ -1,5 +1,4 @@ import logging -import os from datetime import datetime, timezone from pathlib import Path from typing import Any, Dict, Union @@ -9,6 +8,7 @@ from rich.table import Table from rich.theme import Theme +from dstack._internal import settings from dstack._internal.cli.utils.rich import DstackRichHandler from dstack._internal.core.errors import CLIError, DstackError from dstack._internal.utils.common import get_dstack_dir @@ -68,29 +68,22 @@ def configure_logging(): log_file = _get_cli_log_file() - level_names = logging.getLevelNamesMapping() - stdout_level_name = os.getenv("DSTACK_CLI_LOG_LEVEL", "INFO").upper() - stdout_level = level_names[stdout_level_name] - dstack_logger.setLevel(stdout_level) - stdout_handler = DstackRichHandler(console=console) stdout_handler.setFormatter(logging.Formatter(fmt="%(message)s", datefmt="[%X]")) - stdout_handler.setLevel(stdout_level) + stdout_handler.setLevel(settings.CLI_LOG_LEVEL) dstack_logger.addHandler(stdout_handler) - file_level_name = os.getenv("DSTACK_CLI_FILE_LOG_LEVEL", "DEBUG").upper() - file_level = level_names[file_level_name] - file_handler = logging.FileHandler(log_file) file_handler.setFormatter( logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S" ) ) - file_handler.setLevel(file_level) + file_handler.setLevel(settings.CLI_FILE_LOG_LEVEL) dstack_logger.addHandler(file_handler) - dstack_logger.setLevel(min(stdout_level, file_level)) + # the logger allows all messages, filtering is done by the handlers + dstack_logger.setLevel(logging.DEBUG) def confirm_ask(prompt, **kwargs) -> bool: diff --git a/src/dstack/_internal/settings.py b/src/dstack/_internal/settings.py index e07b0ab3c5..608bdd3e17 100644 --- a/src/dstack/_internal/settings.py +++ b/src/dstack/_internal/settings.py @@ -19,6 +19,9 @@ ) DSTACK_DIND_IMAGE = os.getenv("DSTACK_DIND_IMAGE", "dstackai/dind") +CLI_LOG_LEVEL = os.getenv("DSTACK_CLI_LOG_LEVEL", "INFO").upper() +CLI_FILE_LOG_LEVEL = os.getenv("DSTACK_CLI_FILE_LOG_LEVEL", "DEBUG").upper() + # Development settings LOCAL_BACKEND_ENABLED = os.getenv("DSTACK_LOCAL_BACKEND_ENABLED") is not None