Skip to content

Commit 7b3f91f

Browse files
author
server
committed
saved files
1 parent 61d140f commit 7b3f91f

16 files changed

Lines changed: 4312 additions & 0 deletions
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
"""Canonical layout helpers for RAG data, metadata, and utility scripts."""
2+
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env python3
2+
3+
import logging
4+
import os
5+
import sys
6+
from pathlib import Path
7+
8+
_AGENTIC_ROOT = Path(__file__).resolve().parent
9+
_AGENT_LOG_ROOT = _AGENTIC_ROOT / "runtime_data" / "agent-logs"
10+
11+
SYSTEM_LOG_DIRS = {
12+
"ebg_crash": "ebg_crash_logs",
13+
"ebg_plateau": "ebg_plateau_logs",
14+
"fog": "fog_logs",
15+
"services": "service_logs",
16+
}
17+
18+
19+
class StreamToLogger:
20+
def __init__(self, log_fn):
21+
self.log_fn = log_fn
22+
self._buffer = ""
23+
24+
def write(self, message):
25+
if not isinstance(message, str):
26+
message = message.decode("utf-8", errors="ignore")
27+
self._buffer += message
28+
while "\n" in self._buffer:
29+
line, self._buffer = self._buffer.split("\n", 1)
30+
self.log_fn(line)
31+
32+
def flush(self):
33+
if self._buffer:
34+
self.log_fn(self._buffer)
35+
self._buffer = ""
36+
37+
def isatty(self):
38+
return False
39+
40+
41+
def get_agent_log_root() -> Path:
42+
_AGENT_LOG_ROOT.mkdir(parents=True, exist_ok=True)
43+
return _AGENT_LOG_ROOT
44+
45+
46+
def get_system_log_dir(system_name: str) -> Path:
47+
dirname = SYSTEM_LOG_DIRS.get(system_name, system_name)
48+
path = get_agent_log_root() / dirname
49+
path.mkdir(parents=True, exist_ok=True)
50+
return path
51+
52+
53+
def next_log_path(system_name: str, stem: str, suffix: str = ".log") -> Path:
54+
log_dir = get_system_log_dir(system_name)
55+
plain_log = log_dir / f"{stem}{suffix}"
56+
if not plain_log.exists():
57+
return plain_log
58+
59+
latest_num = 0
60+
for existing in log_dir.glob(f"{stem}*{suffix}"):
61+
if existing.name == plain_log.name:
62+
continue
63+
extra = existing.stem[len(stem):]
64+
if extra.isdigit():
65+
latest_num = max(latest_num, int(extra))
66+
return log_dir / f"{stem}{latest_num + 1}{suffix}"
67+
68+
69+
def configure_plain_file_logger(logger: logging.Logger, log_path: Path, level: int = logging.INFO) -> logging.Logger:
70+
logger.handlers.clear()
71+
file_handler = logging.FileHandler(log_path, mode="a", encoding="utf-8")
72+
file_handler.setFormatter(logging.Formatter("%(message)s"))
73+
logger.addHandler(file_handler)
74+
logger.setLevel(level)
75+
logger.propagate = False
76+
logger.disabled = False
77+
return logger
78+
79+
80+
def enable_named_logger_from_env(logger_name: str, level: int = logging.INFO) -> logging.Logger:
81+
log_file = os.getenv("IKA_AGENT_LOG_FILE", "").strip()
82+
logger = logging.getLogger(logger_name)
83+
if not log_file:
84+
logger.disabled = True
85+
return logger
86+
87+
log_path = Path(log_file)
88+
log_path.parent.mkdir(parents=True, exist_ok=True)
89+
return configure_plain_file_logger(logger, log_path, level=level)
90+
91+
92+
def configure_process_logging(
93+
system_name: str,
94+
stem: str,
95+
logger: logging.Logger | None = None,
96+
redirect_stdio: bool = True,
97+
level: int = logging.INFO,
98+
) -> Path:
99+
log_path = next_log_path(system_name, stem)
100+
active_logger = logger or logging.getLogger(f"{system_name}.{stem}")
101+
configure_plain_file_logger(active_logger, log_path, level=level)
102+
103+
os.environ["IKA_AGENT_SYSTEM"] = system_name
104+
os.environ["IKA_AGENT_LOG_DIR"] = str(log_path.parent)
105+
os.environ["IKA_AGENT_LOG_FILE"] = str(log_path)
106+
107+
if redirect_stdio:
108+
sys.stdout = StreamToLogger(active_logger.info)
109+
sys.stderr = StreamToLogger(active_logger.error)
110+
111+
return log_path

0 commit comments

Comments
 (0)