aileen3-core / mcp /src /aileen3_mcp /logging_utils.py
ndurner's picture
add comments
0c163b8
from __future__ import annotations
import logging
import os
from pathlib import Path
# Logging paths used by the MCP package.
# The demo UI links directly to these files, so keep the layout stable.
BASE_CACHE = Path(os.environ.get("AILEEN3_CACHE_DIR", Path.home() / ".cache" / "aileen3"))
LOG_DIR = BASE_CACHE / "logs"
LOG_FILE = LOG_DIR / "aileen3-mcp.log"
PACKAGE_LOGGER_NAME = "aileen3_mcp"
def _resolve_level() -> int:
"""Resolve the log level from ``AILEEN3_LOGLEVEL`` or fall back to INFO."""
level_name = os.environ.get("AILEEN3_LOGLEVEL", "").upper() or "INFO"
level = getattr(logging, level_name, None)
if isinstance(level, int):
return level
# Fallback for non-standard levels
try:
return int(level_name)
except Exception:
return logging.INFO
def configure_logging() -> Path:
"""Configure package logging without turning on DEBUG for third-party libs."""
LOG_DIR.mkdir(parents=True, exist_ok=True)
level = _resolve_level()
pkg_logger = logging.getLogger(PACKAGE_LOGGER_NAME)
pkg_logger.setLevel(level)
pkg_logger.propagate = False # keep third-party noise out of our handler
existing = None
for h in pkg_logger.handlers:
if isinstance(h, logging.FileHandler) and Path(getattr(h, "baseFilename", "")) == LOG_FILE:
existing = h
break
if existing:
existing.setLevel(level)
else:
handler = logging.FileHandler(LOG_FILE, encoding="utf-8")
handler.setLevel(level)
handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s"))
pkg_logger.addHandler(handler)
return LOG_FILE