diff --git a/src/ucode/databricks.py b/src/ucode/databricks.py index 1d32f31..70e1f0a 100644 --- a/src/ucode/databricks.py +++ b/src/ucode/databricks.py @@ -53,12 +53,30 @@ # v1.0.0 is the release that ships `databricks aitools`. MIN_DATABRICKS_CLI_VERSION = (1, 0, 0) TOKEN_REFRESH_INTERVAL_SECONDS = 1800 +DEFAULT_DEBUG_LOG_MAX_BYTES = 1_000_000 +DEFAULT_DEBUG_LOG_BACKUP_COUNT = 3 def _debug_enabled() -> bool: return os.environ.get("UCODE_DEBUG") == "1" +def _debug_log_rotation_config() -> tuple[int, int]: + """Return debug log rotation settings, falling back for invalid values.""" + + def non_negative_int(name: str, default: int) -> int: + try: + value = int(os.environ.get(name, "")) + except ValueError: + return default + return value if value >= 0 else default + + return ( + non_negative_int("UCODE_DEBUG_MAX_BYTES", DEFAULT_DEBUG_LOG_MAX_BYTES), + non_negative_int("UCODE_DEBUG_BACKUP_COUNT", DEFAULT_DEBUG_LOG_BACKUP_COUNT), + ) + + _DEBUG_LOGGER: logging.Logger | None = None @@ -73,12 +91,13 @@ def _get_debug_logger() -> logging.Logger | None: return _DEBUG_LOGGER log_path = APP_DIR / "debug.log" + max_bytes, backup_count = _debug_log_rotation_config() try: log_path.parent.mkdir(parents=True, exist_ok=True) handler = logging.handlers.RotatingFileHandler( log_path, - maxBytes=1_000_000, - backupCount=3, + maxBytes=max_bytes, + backupCount=backup_count, encoding="utf-8", ) handler.setFormatter( diff --git a/tests/test_databricks.py b/tests/test_databricks.py index 7e1a73a..ef6779c 100644 --- a/tests/test_databricks.py +++ b/tests/test_databricks.py @@ -36,6 +36,27 @@ WS = "https://example.databricks.com" +class TestDebugLogRotationConfig: + def test_uses_defaults_when_environment_is_unset(self, monkeypatch): + monkeypatch.delenv("UCODE_DEBUG_MAX_BYTES", raising=False) + monkeypatch.delenv("UCODE_DEBUG_BACKUP_COUNT", raising=False) + + assert db_mod._debug_log_rotation_config() == (1_000_000, 3) + + def test_reads_values_from_environment(self, monkeypatch): + monkeypatch.setenv("UCODE_DEBUG_MAX_BYTES", "25000000") + monkeypatch.setenv("UCODE_DEBUG_BACKUP_COUNT", "10") + + assert db_mod._debug_log_rotation_config() == (25_000_000, 10) + + @pytest.mark.parametrize("value", ["", "invalid", "-1"]) + def test_invalid_values_fall_back_independently(self, monkeypatch, value): + monkeypatch.setenv("UCODE_DEBUG_MAX_BYTES", value) + monkeypatch.setenv("UCODE_DEBUG_BACKUP_COUNT", "8") + + assert db_mod._debug_log_rotation_config() == (1_000_000, 8) + + class TestWorkspaceHostname: def test_extracts_hostname(self): assert workspace_hostname(WS) == "example.databricks.com"