-- K-ArtSell Aegis v16.0 Monitoring Queries -- AGENTS.md Observability Standards -- Reference: CLAUDE.md Operational Dashboards -- ============================================================================ -- PRIORITY 1: BATCH SLA MONITORING -- ============================================================================ -- 1.1 Current Queue Depths (all queues) SELECT queue, COUNT(*) as pending_jobs, MIN(created_at) as oldest_job, AVG(EXTRACT(EPOCH FROM (now() - created_at))) as avg_wait_seconds FROM hangfire.job WHERE state_name IN ('Enqueued', 'Scheduled') GROUP BY queue ORDER BY pending_jobs DESC; -- 1.2 Job Completion Times (last 24 hours, by queue) SELECT queue, COUNT(*) as completed_jobs, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (ended_at - created_at))) as p50_latency_sec, PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (ended_at - created_at))) as p95_latency_sec, PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (ended_at - created_at))) as p99_latency_sec FROM hangfire.job WHERE state_name = 'Succeeded' AND ended_at > now() - interval '24 hours' GROUP BY queue ORDER BY p99_latency_sec DESC; -- 1.3 Failed Jobs (last 24 hours) SELECT id, queue, type, state_name, exception_type, exception_message, created_at, ended_at FROM hangfire.job WHERE state_name = 'Failed' AND created_at > now() - interval '24 hours' ORDER BY ended_at DESC LIMIT 50; -- ============================================================================ -- PRIORITY 2: DATA QUALITY QUARANTINE -- ============================================================================ -- 2.1 DQ-classified Jobs (awaiting manual review) SELECT id, queue, type, state_name, created_at, retry_classification, exception_message FROM hangfire.job WHERE state_data LIKE '%retry_classification%dq%' AND state_name IN ('Failed', 'Scheduled') ORDER BY created_at DESC LIMIT 100; -- 2.2 DQ Jobs by Type (trend analysis) SELECT type, COUNT(*) as dq_count, MAX(created_at) as latest_dq FROM hangfire.job WHERE state_data LIKE '%retry_classification%dq%' AND created_at > now() - interval '7 days' GROUP BY type ORDER BY dq_count DESC; -- ============================================================================ -- PRIORITY 3: DUPLICATE DETECTION & RECONCILIATION -- ============================================================================ -- 3.1 Outbox Duplicate Events (same idempotency key, multiple entries) SELECT idempotency_key, COUNT(*) as duplicate_count, MIN(published_at) as first_published, MAX(published_at) as last_published, event_type FROM outbox.outbox WHERE idempotency_key IS NOT NULL GROUP BY idempotency_key, event_type HAVING COUNT(*) > 1 ORDER BY duplicate_count DESC LIMIT 50; -- 3.2 Inbox Processing Status (pending/processed) SELECT state, COUNT(*) as message_count, MIN(created_at) as oldest, MAX(created_at) as newest FROM inbox.inbox GROUP BY state ORDER BY message_count DESC; -- 3.3 Outbox to Inbox Gap (unprocessed events) SELECT o.id as outbox_id, o.idempotency_key, o.event_type, o.published_at, CASE WHEN i.id IS NOT NULL THEN 'PROCESSED' ELSE 'PENDING' END as status, AGE(now(), o.published_at) as age FROM outbox.outbox o LEFT JOIN inbox.inbox i ON o.idempotency_key = i.idempotency_key WHERE o.published_at > now() - interval '1 hour' ORDER BY o.published_at DESC; -- ============================================================================ -- PRIORITY 4: MODEL DRIFT MONITORING -- ============================================================================ -- 4.1 Shadow Run Completion Status (Gate 5 Progress) SELECT id, model_id, created_at, started_at, completed_at, state_name, AGE(COALESCE(completed_at, now()), started_at) as duration, trading_day_count, pbo_score, dsr_score FROM shadow_runs WHERE created_at > now() - interval '30 days' ORDER BY created_at DESC LIMIT 10; -- 4.2 Model Metrics Trending (OOS performance vs baseline) SELECT model_id, DATE(created_at) as metric_date, AVG(backtest_sharpe) as avg_backtest_sharpe, AVG(oos_sharpe) as avg_oos_sharpe, AVG(oos_sharpe - backtest_sharpe) as sharpe_divergence FROM model_metrics WHERE created_at > now() - interval '90 days' GROUP BY model_id, DATE(created_at) ORDER BY model_id, metric_date DESC; -- ============================================================================ -- PRIORITY 5: SYSTEM HEALTH -- ============================================================================ -- 5.1 Hangfire Server Health (worker counts, CPU) SELECT name, last_heartbeat, worker_count, queue_count, AGE(now(), last_heartbeat) as heartbeat_age FROM hangfire.server ORDER BY last_heartbeat DESC; -- 5.2 Application Error Rates (last 1 hour) SELECT DATE_TRUNC('minute', created_at) as minute, COUNT(*) as error_count, COUNT(CASE WHEN state_name = 'Failed' THEN 1 END) as failed_jobs, COUNT(CASE WHEN exception_type LIKE '%Timeout%' THEN 1 END) as timeout_errors FROM hangfire.job WHERE created_at > now() - interval '1 hour' GROUP BY DATE_TRUNC('minute', created_at) ORDER BY minute DESC; -- 5.3 Database Connection Pool Status (if monitored) SELECT datname as database, usename as user, state, COUNT(*) as connection_count, MAX(EXTRACT(EPOCH FROM (now() - state_change))) as idle_seconds FROM pg_stat_activity WHERE datname = 'kartsell' GROUP BY datname, usename, state ORDER BY connection_count DESC;