The BitzOrcas template defines alert thresholds but does not auto-trigger alerts. An external monitoring system — Prometheus, Datadog, Azure Monitor, or Grafana — scrapes OpenTelemetry metrics and fires the alerts against these thresholds. This page is the reference threshold table and per-signal runbook; Monitoring and alerting covers the generic observability setup.
Alert thresholds
| Metric | Source | Warning | Severe | Frequency |
|---|---|---|---|---|
/health/ready failure | K8s readiness probe | 1 consecutive failure | 3 consecutive failures | every 10s |
| HTTP 5xx error rate | OTel http.server.request.duration | >1% (5min) | >5% (5min) | every 30s |
| CAP outbox backlog | Cap.Published, undelivered rows | >100 rows | >1000 rows | every 1min |
| Job consecutive failure | Success/ErrorCode from /api/audit?Category=BackgroundJob | 1 failure | 3 failures | per cron cycle |
| Audit write backlog | audit channel queue depth | >10000 entries | >50000 entries | every 1min |
| Seed initialization failure | --init-schema CLI exit code (no platform REST endpoint) | any non-zero | — | execution-time |
| InMemory/Null adapter in production | GET /api/operations/adapters | any critical port = Default/Unavailable | — | every 5min |
| Missing/weak key config | GET /api/operations/config | any required missing/too-short | — | every 5min |
| Unauthorized Operations access | /api/audit?Category=Security | single IP >10/min | >50/min | real-time |
Per-signal diagnostic runbook
The common shape: read the Operations adapter/config endpoint, inspect the named subsystem, check dependent infrastructure (SQL/RabbitMQ/Redis), remediate config, restart or rolling-redeploy, and confirm recovery via the health probe.
/health/ready consecutive failure
GET /api/operations/adapters— identify which readiness-tagged health check failed.GET /api/operations/config— confirm the connection string and RabbitMQ config.- Connect to SQL Server and run
SELECT 1to confirm reachability. - Check the RabbitMQ management UI for connection count and queue state.
- If the dependency recovers, Kubernetes auto-resumes traffic distribution.
HTTP 5xx error rate spike
GET /api/audit?Category=Exception&From=<5min-ago>— read the restricted envelope, then correlate logs and traces by CorrelationId for details.- Inspect the OTel trace to find the top error endpoint.
- For an EF Core/SqlSugar exception, check the DB connection pool and deadlocks.
- For OOM, check
dotnet-countersGC and heap size.
CAP outbox backlog
- RabbitMQ management UI — confirm the
bitzorcas.*exchange has consumers. SELECT COUNT(*) FROM Cap.Published WHERE Retries < 50— view the backlog volume.- If consumers are not registered, check that the API/JobHost started correctly.
- If RabbitMQ is unreachable, CAP auto-retries; the backlog drains on recovery.
Job consecutive failure
GET /api/audit?Category=BackgroundJob&Module=Auditing— read job outcomes and stable error codes, then correlate logs for exception details.- If
IAuditRetentionPortis not registered, confirmAddBitzOrcasSqlSugarAuditStorewas called. - For an SQL execution timeout, check the audit table index and data volume.
- Manual rerun via
scripts/database/seed-demo.sh(seed problem) or a JobHost restart.
InMemory/Null adapter in production
GET /api/operations/adapters— confirm which ports are Default/Unavailable.GET /api/operations/config— confirmConnectionStrings:DefaultandRabbitMq:Hostare configured.- If config is missing, inject via environment variables and rolling-restart.
- If config is correct but the adapter is still Default, inspect the branch logic in
PersistenceRegistration.
Missing/weak key config
GET /api/operations/config— find the missing or too-short keys.- Inject the correct value via the K8s Secret / Key Vault.
- Rolling-restart.
Evidence capture before and after remediation
Preserve base health, adapter, and configuration diagnostics first. Capture all three from the same instance and time window, and keep secret fields out of the incident attachment:
# Base readiness and runtime-composition snapshot.curl -fsS https://<HOST>/health/ready > ready.jsoncurl -fsS -H "Authorization: Bearer <TOKEN>" \ https://<HOST>/api/operations/adapters > adapters.jsoncurl -fsS -H "Authorization: Bearer <TOKEN>" \ https://<HOST>/api/operations/config > config-diagnostics.jsonAfter recovery, repeat the audit capture over the same window. The query endpoint has no Result parameter; aggregate returned Success and ErrorCode values instead of assuming an unknown query key was applied:
# Keep the incident boundary so before/after job evidence remains comparable.curl -fsS --get -H "Authorization: Bearer <TOKEN>" \ --data-urlencode "category=BackgroundJob" --data-urlencode "module=Auditing" \ --data-urlencode "from=<INCIDENT-START-UTC>" --data-urlencode "pageSize=200" \ https://<HOST>/api/audit > background-jobs.jsonMonitoring-system integration
| Monitoring system | Collection method |
|---|---|
| Prometheus | OTel Collector → Prometheus exporter; scrape /metrics |
| Datadog | OTel Collector → Datadog exporter |
| Azure Monitor | OTel Collector → Azure Monitor exporter |
| Kubernetes | readiness/liveness probe → auto-alert |
| Grafana | OTel → Tempo (traces) + Prometheus (metrics) + Loki (logs) |