From 9d34753d0fdd04d1803144e598ca5ec2e9d46fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=8A?= Date: Mon, 2 Mar 2026 10:51:45 +0530 Subject: [PATCH] Add structured warning logs for memory and semantic fallback paths --- backend/api/today_workflow.py | 9 +++++- .../monitoring/semantic_dashboard.py | 32 ++++++++++++++++--- backend/services/task_memory_service.py | 23 +++++++++++-- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/backend/api/today_workflow.py b/backend/api/today_workflow.py index 095e1ad7..264f1a48 100644 --- a/backend/api/today_workflow.py +++ b/backend/api/today_workflow.py @@ -1,6 +1,7 @@ from fastapi import APIRouter, Depends, HTTPException from typing import Any, Dict, Optional from datetime import datetime +from loguru import logger from sqlalchemy.orm import Session @@ -182,7 +183,13 @@ async def set_task_status( feedback_text=completion_notes ) except Exception as e: - pass # Don't block response on memory update failure + logger.warning( + "Task memory outcome recording failed for user_id={} task_id={} error_class={} error_message={}", + user_id, + task_id, + type(e).__name__, + str(e), + ) plan_for_date = db.query(DailyWorkflowPlan).filter(DailyWorkflowPlan.id == task.plan_id).first() plan_date = plan_for_date.date if plan_for_date and plan_for_date.date else "" diff --git a/backend/services/intelligence/monitoring/semantic_dashboard.py b/backend/services/intelligence/monitoring/semantic_dashboard.py index 5880690a..701f86ee 100644 --- a/backend/services/intelligence/monitoring/semantic_dashboard.py +++ b/backend/services/intelligence/monitoring/semantic_dashboard.py @@ -368,9 +368,15 @@ class RealTimeSemanticMonitor: # Using StrategyArchitect for pillar/gap analysis if hasattr(self.strategy_agent, 'find_semantic_gaps'): - # This method requires competitor indices, which is complex to get here without full context. - # Let's use the SIF service directly for lighter weight insights or call the agent's high level method. - pass + logger.warning( + "Skipping direct semantic gap method invocation for user_id={} due to missing competitor index context", + self.user_id, + ) + else: + logger.warning( + "Strategy agent missing find_semantic_gaps for user_id={}, using dashboard-context fallback", + self.user_id, + ) # Alternative: Query SIF directly for "content gaps" if they are indexed as such # Or generate them now via LLM + SIF Context @@ -422,6 +428,17 @@ class RealTimeSemanticMonitor: source_agent="Strategy Architect Agent" )) + if not ai_insights: + logger.warning( + "Dashboard context returned no ai_insights for user_id={}, insight generation is degraded", + self.user_id, + ) + else: + logger.warning( + "SEO dashboard context unavailable for user_id={}, using fallback insight only", + self.user_id, + ) + except Exception as agent_err: logger.warning(f"Agent insight generation failed: {agent_err}") @@ -514,8 +531,13 @@ class RealTimeSemanticMonitor: dedupe_key=dedupe_key, ) db.close() - except Exception: - pass + except Exception as alert_err: + logger.warning( + "Unable to persist semantic alerts for user_id={} error_class={} error_message={}", + self.user_id, + type(alert_err).__name__, + str(alert_err), + ) await self._send_alerts(alerts) async def get_cache_stats(self) -> Dict[str, Any]: diff --git a/backend/services/task_memory_service.py b/backend/services/task_memory_service.py index f379deb4..94cab477 100644 --- a/backend/services/task_memory_service.py +++ b/backend/services/task_memory_service.py @@ -30,6 +30,17 @@ class TaskMemoryService: self.user_id = user_id self.db = db self.intelligence = TxtaiIntelligenceService(user_id) + self._metrics_counters: Dict[str, int] = {} + + def _increment_metric(self, metric_name: str, increment: int = 1) -> None: + """Increment lightweight in-memory counters for observability hooks.""" + self._metrics_counters[metric_name] = self._metrics_counters.get(metric_name, 0) + increment + logger.debug( + "TaskMemory metric updated user_id={} metric={} value={}", + self.user_id, + metric_name, + self._metrics_counters[metric_name], + ) def _compute_hash(self, title: str, description: str) -> str: """Compute a consistent hash for task deduplication.""" @@ -154,8 +165,16 @@ class TaskMemoryService: f"Filtering redundant task (semantic {top_score:.2f}, history status={history_status}): {p.title}" ) is_semantic_duplicate = True - except Exception: - pass + except Exception as semantic_err: + self._increment_metric("semantic_filter_failures") + self._increment_metric("semantic_filter_degraded_path_taken") + logger.warning( + "Semantic filter degraded for user_id={} proposal_title={} error_class={} error_message={}", + self.user_id, + getattr(p, "title", ""), + type(semantic_err).__name__, + str(semantic_err), + ) if not is_semantic_duplicate: filtered.append(p)