# Production alert rules for VigilCare Clinical. # Load via Prometheus rule_files / alerting config on the external Prometheus host. # Metric names match VigilCareClinicalAPI/Observability/Metrics/ClinicalMetrics.cs. groups: - name: vigilcare_production rules: - alert: VigilCareApiDown expr: up{job="vigilcare_api_prod"} == 0 for: 2m labels: severity: critical service: clinical-api annotations: summary: "VigilCare Clinical API is down" description: "Prometheus cannot scrape vigilcare_api_prod for more than 2 minutes." - alert: VigilCareOutboxBacklog expr: outbox_pending_events{job="vigilcare_api_prod"} > 1000 for: 5m labels: severity: warning service: clinical-api annotations: summary: "Outbox backlog is growing" description: "outbox_pending_events is {{ $value }} (threshold 1000). Alert delivery to Kafka consumers is delayed." - alert: VigilCareKafkaConsumerLag expr: kafka_consumer_lag{job="vigilcare_api_prod"} > 10000 for: 10m labels: severity: warning service: clinical-api annotations: summary: "Kafka consumer lag high for {{ $labels.consumer_group }}" description: "consumer_group={{ $labels.consumer_group }} lag={{ $value }} (threshold 10000)." # Prefer the blackbox probe job if configured; otherwise treat scrape failure # of the API as covering liveness. This rule fires when the ready probe exists # and reports failure. - alert: VigilCareReadyCheckFailing expr: probe_success{job="vigilcare_api_ready_probe"} == 0 for: 3m labels: severity: critical service: clinical-api annotations: summary: "API /health/ready is failing" description: "Blackbox probe of /health/ready has been failing for 3 minutes." # GatewayStaleDetectorService marks stale gateways OFFLINE; the collector # exposes them as ward_gateways_offline_gauge (site_code label). - alert: VigilCareGatewayStale expr: sum(ward_gateways_offline_gauge{job="vigilcare_api_prod"}) > 0 for: 5m labels: severity: warning service: clinical-api annotations: summary: "One or more ward gateways are offline/degraded" description: "{{ $value }} gateway(s) offline. Stale threshold is GatewayMonitoring:StaleThresholdMinutes (default 10)." - alert: VigilCareCriticalAlertsUnacked expr: alerts_unacknowledged_gauge{job="vigilcare_api_prod"} > 0 for: 5m labels: severity: critical service: clinical-api annotations: summary: "Unacknowledged CRITICAL alerts" description: "{{ $value }} CRITICAL alert(s) older than 5 minutes with no acknowledgment."