File size: 2,570 Bytes
3fb9411
 
 
 
 
 
 
0c163b8
 
 
3fb9411
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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"]