feat(agent-centric-logging): consolidate CoT infra in shared, close REASON→REFLECT chains
- shared/cot_logger.py is SSOT; backend/cot_logger.py deleted
- elapsed_ms timing in all REFLECT markers
- Frontend: REASON→REFLECT/EXPLORE in all fetch/post/delete/requestApi
- Dynamic src: route.GET.api.plugins instead of hardcoded api.request_handler
- trace_id generated immediately (no 'no-trace'), X-Trace-ID in both directions
- Global error handlers (window error + unhandledrejection + error.svelte)
- Fixed duplicate logging (shared/logger.py double StreamHandler)
- propagate=False in configure_logger (was in ConfigManager = duplicated startup logs)
- belief_scope: 'Coherence OK' → '{anchor}: completed' + elapsed_ms
- Fixed 28 pre-existing test failures (scheduler sig, DB columns, DRAFT validation, etc)
This commit is contained in:
@@ -65,7 +65,7 @@ from .api.routes import (
|
||||
)
|
||||
from .api.routes.validation_tasks import router as validation_tasks
|
||||
from .core.auth.security import get_password_hash
|
||||
from .core.cot_logger import get_trace_id, seed_trace_id
|
||||
from ss_tools.shared.cot_logger import get_trace_id, seed_trace_id
|
||||
from .core.database import AuthSessionLocal, init_db
|
||||
from .core.encryption_key import ensure_encryption_key
|
||||
from .core.logger import belief_scope, logger
|
||||
@@ -90,11 +90,11 @@ async def lifespan(app: FastAPI):
|
||||
# Startup
|
||||
seed_trace_id()
|
||||
with belief_scope("startup_event"):
|
||||
logger.reason("Ensuring encryption key")
|
||||
logger.reason("Ensure encryption subsystem availability")
|
||||
ensure_encryption_key()
|
||||
logger.reason("Initializing database tables")
|
||||
logger.reason("Initialize persistent database tables")
|
||||
init_db()
|
||||
logger.reason("Bootstrapping admin user")
|
||||
logger.reason("Bootstrap initial admin user (idempotent)")
|
||||
ensure_initial_admin_user()
|
||||
# Clean up stuck validation runs from previous backend lifetime
|
||||
# (runs left "running" in DB when the in-memory task queue was lost)
|
||||
@@ -412,26 +412,27 @@ async def log_requests(request: Request, call_next):
|
||||
if not get_trace_id():
|
||||
seed_trace_id()
|
||||
with belief_scope("log_requests"):
|
||||
# Avoid spamming logs for polling endpoints
|
||||
is_polling = request.url.path.endswith("/api/tasks") and request.method == "GET"
|
||||
# Dynamic src derived from the request route — more informative than hardcoded "api.request_handler"
|
||||
_route_path = request.url.path.strip("/").replace("/", ".")
|
||||
_src = f"route.{request.method}.{_route_path}" if _route_path else f"route.{request.method}.root"
|
||||
is_polling = (
|
||||
(request.url.path.endswith("/api/tasks") and request.method == "GET")
|
||||
or request.url.path.endswith("/api/health/summary")
|
||||
)
|
||||
if not is_polling:
|
||||
import json as _json, logging as _lg
|
||||
|
||||
if logger.isEnabledFor(_lg.INFO):
|
||||
logger.reason("Incoming request", payload={"method": request.method, "path": request.url.path})
|
||||
else:
|
||||
_json.dump({"ts": __import__("datetime").datetime.now(__import__("datetime").UTC).isoformat(), "level": "INFO", "src": "log_requests", "marker": "REASON", "intent": f"Incoming request: {request.method} {request.url.path}"}, sys.stderr, ensure_ascii=False)
|
||||
sys.stderr.write("\n")
|
||||
sys.stderr.flush()
|
||||
logger.reason(
|
||||
"Handle API request",
|
||||
src=_src,
|
||||
payload={"method": request.method, "path": request.url.path}
|
||||
)
|
||||
try:
|
||||
response = await call_next(request)
|
||||
if not is_polling:
|
||||
if logger.isEnabledFor(_lg.INFO):
|
||||
logger.reflect("Response", payload={"status": response.status_code, "path": request.url.path})
|
||||
else:
|
||||
_json.dump({"ts": __import__("datetime").datetime.now(__import__("datetime").UTC).isoformat(), "level": "INFO", "src": "log_requests", "marker": "REFLECT", "intent": f"Response: {response.status_code} for {request.url.path}"}, sys.stderr, ensure_ascii=False)
|
||||
sys.stderr.write("\n")
|
||||
sys.stderr.flush()
|
||||
logger.reflect(
|
||||
"API request completed",
|
||||
src=_src,
|
||||
payload={"status": response.status_code, "path": request.url.path}
|
||||
)
|
||||
return response
|
||||
except NetworkError as e:
|
||||
logger.explore("Network error caught in middleware", error=str(e))
|
||||
|
||||
Reference in New Issue
Block a user