logs: migrate to molecular CoT JSON protocol, fix regressions

- Replace BeliefFormatter with CotJsonFormatter (single-line JSON with
  ts, level, trace_id, src, marker, intent, payload, error, span_id)
- Migrate belief_scope to use cot_log() for structured JSON output
- Update monkey-patched reason/reflect/explore to pass extra= dict
- Strip 200+ inline [REASON]/[REFLECT]/[EXPLORE] markers from 50+ files
- Remove belief_scope from hot-path utilities (_parse_datetime,
  _json_load_if_needed) to eliminate startup log noise
- Register TraceContextMiddleware in app.py (was implemented but unused)
- Seed trace_id in startup_event/shutdown_event for background tasks
- Fix broken relative imports in translate routes (3 dots → 4 dots)
- Migrate 43 translate_routes log calls to logger.reason/explore
- Fix SyntaxError (positional arg after extra=) in _repo_operations_routes
- Fix IndentationError in rbac_permission_catalog except-block
- Add smoke test tests/test_smoke_app.py (catches import errors before run)
This commit is contained in:
2026-05-13 09:44:50 +03:00
parent b6f46fe9f5
commit 83b8f4d999
55 changed files with 644 additions and 539 deletions

View File

@@ -61,8 +61,9 @@ def _resolve_repository_status(dashboard_id: int) -> dict:
git_service = get_git_service()
repo_path = git_service._get_repo_path(dashboard_id)
if not os.path.exists(repo_path):
logger.debug(
f"[get_repository_status][REASON] Repository is not initialized for dashboard {dashboard_id}"
logger.reason(
f"Repository is not initialized for dashboard {dashboard_id}",
extra={"src": "get_repository_status"},
)
return _build_no_repo_status_payload()
@@ -70,8 +71,9 @@ def _resolve_repository_status(dashboard_id: int) -> dict:
return git_service.get_status(dashboard_id)
except HTTPException as e:
if e.status_code == 404:
logger.debug(
f"[get_repository_status][REASON] Repository is not initialized for dashboard {dashboard_id}"
logger.reason(
f"Repository is not initialized for dashboard {dashboard_id}",
extra={"src": "get_repository_status"},
)
return _build_no_repo_status_payload()
raise
@@ -287,10 +289,9 @@ def _resolve_current_user_git_identity(
.first()
)
except Exception as resolve_error:
logger.warning(
"[_resolve_current_user_git_identity][REASON] Failed to load profile preference for user %s: %s",
user_id,
resolve_error,
logger.explore(
"Failed to load profile preference for resolving git identity",
extra={"src": "_resolve_current_user_git_identity", "payload": {"user_id": user_id}, "error": str(resolve_error)},
)
return None

View File

@@ -128,23 +128,17 @@ async def pull_changes(
config_url = config_row.url
config_provider = config_row.provider
except Exception as diagnostics_error:
logger.warning(
"[pull_changes][REASON] Failed to load repository binding diagnostics for dashboard %s: %s",
dashboard_id,
diagnostics_error,
logger.explore(
"Failed to load repository binding diagnostics",
extra={"src": "pull_changes", "payload": {"dashboard_id": dashboard_id}, "error": str(diagnostics_error)},
)
logger.info(
"[pull_changes][REASON] Route diagnostics dashboard_ref=%s env_id=%s resolved_dashboard_id=%s "
"binding_exists=%s binding_local_path=%s binding_remote_url=%s binding_config_id=%s config_provider=%s config_url=%s",
dashboard_ref,
env_id,
dashboard_id,
bool(db_repo),
(db_repo.local_path if db_repo else None),
(db_repo.remote_url if db_repo else None),
(db_repo.config_id if db_repo else None),
config_provider,
config_url,
logger.reason(
f"Route diagnostics dashboard_ref={dashboard_ref} env_id={env_id} resolved_dashboard_id={dashboard_id} "
f"binding_exists={bool(db_repo)} binding_local_path={(db_repo.local_path if db_repo else None)} "
f"binding_remote_url={(db_repo.remote_url if db_repo else None)} "
f"binding_config_id={(db_repo.config_id if db_repo else None)} "
f"config_provider={config_provider} config_url={config_url}",
extra={"src": "pull_changes"},
)
_apply_git_identity_from_profile(dashboard_id, db, current_user)
_gs.pull_changes(dashboard_id)
@@ -190,10 +184,9 @@ async def get_repository_status_batch(
with belief_scope("get_repository_status_batch"):
dashboard_ids = list(dict.fromkeys(request.dashboard_ids))
if len(dashboard_ids) > MAX_REPOSITORY_STATUS_BATCH:
logger.warning(
"[get_repository_status_batch][REASON] Batch size %s exceeds limit %s. Truncating request.",
len(dashboard_ids),
MAX_REPOSITORY_STATUS_BATCH,
logger.reason(
f"Batch size {len(dashboard_ids)} exceeds limit {MAX_REPOSITORY_STATUS_BATCH}. Truncating request.",
extra={"src": "get_repository_status_batch"},
)
dashboard_ids = dashboard_ids[:MAX_REPOSITORY_STATUS_BATCH]

View File

@@ -61,8 +61,9 @@ async def init_repository(
raise HTTPException(status_code=404, detail="Git configuration not found")
try:
logger.info(
f"[init_repository][REASON] Initializing repo for dashboard {dashboard_id}"
logger.reason(
f"Initializing repo for dashboard {dashboard_id}",
extra={"src": "init_repository"},
)
_gs.init_repo(
dashboard_id,