Spaces:
Running
Running
| from __future__ import annotations | |
| import logging | |
| import os | |
| from pathlib import Path | |
| from typing import Optional | |
| # Lightweight logging helper for the Gradio demo. | |
| # The MCP server has its own logging configuration; this module keeps | |
| # demo-specific logs in a separate file referenced from the UI. | |
| LOGGER_NAME = "aileen3_demo" | |
| LOG_LEVEL_ENV = "AILEEN3_DEMO_LOGLEVEL" | |
| _configured = False | |
| _log_file_path: Path | None = None | |
| def _resolve_level() -> int: | |
| level_name = (os.environ.get(LOG_LEVEL_ENV) or "INFO").upper() | |
| level = getattr(logging, level_name, None) | |
| if isinstance(level, int): | |
| return level | |
| try: | |
| return int(level_name) | |
| except Exception: | |
| return logging.INFO | |
| def _pick_log_path() -> Path: | |
| primary_base = Path(os.environ.get("AILEEN3_CACHE_DIR", Path.home() / ".cache" / "aileen3")) | |
| primary = primary_base / "logs" / "aileen3-demo.log" | |
| fallback = Path.cwd() / ".aileen3_logs" / "aileen3-demo.log" | |
| for candidate in (primary, fallback): | |
| try: | |
| candidate.parent.mkdir(parents=True, exist_ok=True) | |
| with open(candidate, "a", encoding="utf-8"): | |
| pass | |
| return candidate | |
| except PermissionError: | |
| continue | |
| except OSError: | |
| continue | |
| # Last resort: stderr-only logger | |
| return fallback | |
| def _ensure_logger() -> None: | |
| global _configured, _log_file_path | |
| if _configured: | |
| return | |
| level = _resolve_level() | |
| logger = logging.getLogger(LOGGER_NAME) | |
| logger.setLevel(level) | |
| logger.propagate = False | |
| log_path = _pick_log_path() | |
| _log_file_path = log_path | |
| try: | |
| handler = logging.FileHandler(log_path, encoding="utf-8") | |
| handler.setLevel(level) | |
| handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s")) | |
| logger.addHandler(handler) | |
| except Exception: | |
| # Fallback to stderr only | |
| handler = logging.StreamHandler() | |
| handler.setLevel(level) | |
| handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s")) | |
| logger.addHandler(handler) | |
| _configured = True | |
| def get_demo_logger(name: Optional[str] = None) -> logging.Logger: | |
| """Return a logger that writes into a cache or repo-local log file.""" | |
| _ensure_logger() | |
| return logging.getLogger(name or LOGGER_NAME) | |
| def get_demo_log_path() -> Path: | |
| _ensure_logger() | |
| return _log_file_path or Path(".aileen3_logs/aileen3-demo.log") | |
| __all__ = ["get_demo_logger", "get_demo_log_path"] | |