refactor(prax): simplify logging from hierarchical to two-tier

Remove get_hierarchical_logs_dir() and all nested log placement logic.
Local logs now route to branch-root logs/ only, matching system_logs/
at repo root for a clean two-tier model.

Co-Authored-By: @prax <prax@aipass>
This commit is contained in:
AIOSAI
2026-03-16 23:56:57 -07:00
co-authored by @prax
parent 79b09e8c1d
commit 3a55e0b8b4
2 changed files with 4 additions and 58 deletions
+1 -39
View File
@@ -73,8 +73,7 @@ def get_module_logs_dir(module_name: str) -> Path:
"""Get the branch-root logs directory for a module.
Returns ECOSYSTEM_ROOT / module_name / "logs", creating it if needed.
For hierarchical placement (logs at the caller's level), use
get_hierarchical_logs_dir() instead.
All branch-local logs are placed here (two-tier: system_logs/ + branch logs/).
Args:
module_name: Module name (e.g., "flow", "prax", "trigger")
@@ -86,43 +85,6 @@ def get_module_logs_dir(module_name: str) -> Path:
logs_dir.mkdir(parents=True, exist_ok=True)
return logs_dir
def get_hierarchical_logs_dir(caller_path: str) -> Path:
"""Get the logs directory at the caller's level in the code hierarchy.
Resolves a logs/ directory as a sibling of the caller's parent directory.
Logs live where the code lives:
handlers/dispatch/wake.py → handlers/dispatch/logs/
modules/email.py → modules/logs/
apps/branch.py → apps/logs/
Falls back to branch-root logs/ if the caller is outside the
ecosystem or path resolution fails.
Args:
caller_path: Absolute path to the calling Python file
Returns:
Path to the logs directory (created if it doesn't exist)
"""
try:
caller = Path(caller_path).resolve()
caller_dir = caller.parent
# Verify caller is inside the ecosystem
try:
caller.relative_to(ECOSYSTEM_ROOT)
except ValueError:
# Outside ecosystem — fall back to branch root
return get_module_logs_dir("prax")
logs_dir = caller_dir / "logs"
logs_dir.mkdir(parents=True, exist_ok=True)
return logs_dir
except Exception:
return get_module_logs_dir("prax")
# Config file
PRAX_LOGGER_CONFIG_FILE = PRAX_JSON_DIR / "prax_logger_config.json"
+3 -19
View File
@@ -22,7 +22,6 @@ from logging.handlers import RotatingFileHandler
from aipass.prax.apps.handlers.config.load import (
get_system_logs_dir,
get_module_logs_dir,
get_hierarchical_logs_dir,
DEFAULT_LOG_LEVEL,
load_log_config,
lines_to_bytes
@@ -118,24 +117,9 @@ def setup_individual_logger(module_name: str) -> logging.Logger:
system_handler.setFormatter(formatter)
logger.addHandler(system_handler)
# HANDLER 2: Hierarchical local log (logs live where the code lives)
if module_path:
hierarchical_logs_dir = get_hierarchical_logs_dir(module_path)
# Detect fallback: caller was in ecosystem but resolution fell back
expected_logs = Path(module_path).resolve().parent / "logs"
if hierarchical_logs_dir.resolve() != expected_logs.resolve() and _system_logger:
_system_logger.warning(
f"Log placement fallback for {module_name}: "
f"caller outside ecosystem, logs redirected to {hierarchical_logs_dir}"
)
else:
hierarchical_logs_dir = get_module_logs_dir(branch_name)
if _system_logger:
_system_logger.warning(
f"Log placement fallback for {module_name}: "
f"stack introspection failed, using branch root {hierarchical_logs_dir}"
)
module_log_file = hierarchical_logs_dir / f"{module_name}.log"
# HANDLER 2: Branch-root local log (two-tier: system_logs/ + branch logs/)
local_logs_dir = get_module_logs_dir(branch_name)
module_log_file = local_logs_dir / f"{module_name}.log"
local_limits = log_config['local_logs']
local_max_bytes = lines_to_bytes(local_limits['max_lines'])
local_handler = _safe_rotating_handler(module_log_file, local_max_bytes, local_limits['backup_count'])