Skip to content

Proposal: database offline / unhealthy-state alert (baseline-deviation) #1986

Description

@jakemorgangit

Hi Erik — I've built a database-state alert in my fork and, per CONTRIBUTING, wanted to check whether you'd welcome it upstream (and how you'd want it shaped) before opening a PR.

The gap

There's currently no alert when a monitored database leaves a healthy state. database_config captures state_desc, but it's a load-time snapshot (frequency 0), so a database going OFFLINE / SUSPECT / RECOVERY_PENDING / RESTORING after a server is added is never surfaced.

Proposed approach: baseline-deviation (not "anything ≠ ONLINE")

A naive "alert on any non-ONLINE state" is too noisy — log-shipping secondaries sit permanently in RESTORING, and some databases are intentionally OFFLINE. Instead:

  • A lightweight per-minute database_states collector captures sys.databases.state_desc as a time series (a few rows against in-memory catalog metadata).
  • Each database's expected state is captured automatically on first observation (a baseline), stored per (server, database).
  • The alert fires when current state ≠ expected. Severity CRITICAL for SUSPECT / RECOVERY_PENDING / EMERGENCY, WARNING otherwise. Per-database cooldown + resolution, routed through the existing mute rules and delivery channels.
  • Operators can override the expected state per database (or set (ignore)) to kill false positives. A log-shipping secondary baselines at RESTORING and stays quiet with zero config; an intentionally-offline database stays quiet too.

Validated against a live SQL Server: baseline capture on first observation, deviation firing with the correct severity, the (ignore) override suppressing a database, and recovery/resolution all worked as intended.

Scope (as built in my fork)

  • Shared: new database_states collector (catalog + schedule defaults), an AlertEngine check, a read-adapter method + settings flag, and the per-metric severity mapping.
  • Stores: Lite DuckDB (auto-created tables) and Darling Postgres — one additive migration: the collector table, a per-(server, database) expected-state config table, and a master-toggle column on the alert-settings row.
  • UI: a settings enable toggle plus a per-database override editor window in both Lite and the Darling Viewer; the web viewer shows fired alerts automatically; the MCP get_alert_settings / update_alert_settings tools expose the toggle.

Questions

  1. Would you want this upstream?
  2. If so, anything about the approach you'd want done differently before I open a PR?

Happy to adjust to fit the project's direction — thanks for taking a look.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions