feat(logging): add configurable logging with file output support

Introduce --log-level and --log-file CLI arguments.
Add execution time tracking and detailed logs across all modules.
This commit is contained in:
2026-04-02 10:40:39 +08:00
parent eef3464257
commit 0bdebd5368
8 changed files with 248 additions and 15 deletions

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
import logging
import re
from typing import Self
@@ -9,6 +10,9 @@ from dotenv import load_dotenv
import os
logger = logging.getLogger(__name__)
@dataclass(slots=True)
class Settings:
api_key: str | None
@@ -18,19 +22,29 @@ class Settings:
@classmethod
def from_env(cls, env_file: Path | None = None, model_override: str | None = None) -> Self:
if env_file:
logger.info("Loading environment variables from %s", env_file)
load_dotenv(env_file)
else:
logger.debug("Loading environment variables using default dotenv lookup")
load_dotenv()
return cls(
settings = cls(
api_key=os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY"),
base_url=os.getenv("GEMINI_BASE_URL") or None,
model=model_override or os.getenv("GEMINI_MODEL") or "gemini-2.5-flash",
)
logger.info(
"Configuration loaded: model=%s base_url=%s api_key=%s",
settings.model,
settings.normalized_base_url() or "<default>",
"set" if settings.api_key else "missing",
)
return settings
def require_api_key(self) -> None:
if not self.api_key:
raise ValueError("Missing GEMINI_API_KEY (or GOOGLE_API_KEY) in the environment.")
logger.debug("Gemini API key is available")
def normalized_base_url(self) -> str | None:
if not self.base_url: