Skip to content

Alert Muting Feature — Implementation Plan #493

@HannahVernon

Description

@HannahVernon

Which component(s) does this affect?

  • Full Dashboard
  • Lite
  • SQL collection scripts
  • Installer
  • Documentation

Problem Statement

Users cannot suppress specific recurring alerts. The only existing options are coarse-grained:

  • Server silencing — suppresses ALL alerts for an entire server
  • Acknowledgement — temporarily hides badges until conditions worsen
  • Database exclusion — filters entire databases from blocking/deadlock counts

There is no way to say "stop alerting me about this specific long-running query" or "mute all blocking alerts from database X" while keeping other alerts active.

Proposed Solution

Add a mute rule system that sits between alert detection and notification. Muted alerts are still collected and logged (with a muted flag) but suppressed from tray notifications, emails, and UI badges.

Two muting modes:

  • Pattern-based: match on server, metric type, database, query text substring, wait type, or job name (fields combined with AND logic)
  • Instance-based: a tightly-scoped pattern rule auto-populated from a specific alert's context

Data Model

public class MuteRule
{
    public string Id { get; set; }               // GUID
    public bool Enabled { get; set; } = true;
    public DateTime CreatedAtUtc { get; set; }
    public DateTime? ExpiresAtUtc { get; set; }  // null = permanent
    public string? Reason { get; set; }          // user note

    // Match criteria — all non-null fields must match (AND)
    public string? ServerName { get; set; }      // exact match, null = any
    public string? MetricName { get; set; }      // exact: "Blocking", "Deadlocks", "High CPU", etc.
    public string? DatabasePattern { get; set; } // substring (case-insensitive)
    public string? QueryTextPattern { get; set; }// substring (case-insensitive)
    public string? WaitTypePattern { get; set; } // substring (case-insensitive)
    public string? JobNamePattern { get; set; }  // substring (case-insensitive)
}

Alert Context for Matching

public class AlertContext
{
    public string ServerName { get; set; }
    public string MetricName { get; set; }       // "Blocking", "Deadlocks", "High CPU", etc.
    public string? DatabaseName { get; set; }
    public string? QueryText { get; set; }
    public string? WaitType { get; set; }
    public string? JobName { get; set; }
}

Integration Points

DashboardEvaluateAlertConditionsAsync() in MainWindow.xaml.cs:

  • After each metric's threshold check passes, before sending notifications
  • Call _muteRuleService.IsAlertMuted(context) with available detail
  • If muted: log alert with Muted=true, skip tray/email/badge

LiteCheckPerformanceAlerts() in MainWindow.xaml.cs:

  • Same pattern: check mute rules per-metric after threshold triggers
  • If muted: log to DuckDB with muted=TRUE, skip tray/email

Persistence

Dashboard: alert_mute_rules.json in %APPDATA%\PerformanceMonitorDashboard\
Lite: New DuckDB table config_mute_rules

UI

  • Alert History tab: right-click context menu → "Mute This Alert" / "Mute Similar Alerts..."
  • Mute Rule Dialog: create/edit form with match fields, expiration picker (1h/24h/7d/permanent), reason text
  • Manage Mute Rules Window: list all rules, enable/disable/delete, accessible from Settings
  • Visual indicator: muted alerts shown grayed/italic in alert history with a "muted" label

Use Case

Alerts which happen frequently, and are well-known, but cannot be immediately actioned, could be muted for a period of time, or muted permanently on a case-by-case basis.

Alternatives Considered

No response

Additional Context

Phase 1: Core Model & Service

  1. model-mute-rule — Create MuteRule model class (both editions)
  2. service-mute-rule-dashboard — Create MuteRuleService for Dashboard (JSON persistence, match logic)
  3. service-mute-rule-lite — Create MuteRuleService for Lite (DuckDB persistence, match logic)
  4. lite-schema-update — Add config_mute_rules table + muted column to config_alert_log in Schema.cs

Phase 2: Alert Pipeline Integration

  1. integrate-dashboard-eval — Wire mute checks into EvaluateAlertConditionsAsync (per-metric)
  2. integrate-lite-eval — Wire mute checks into CheckPerformanceAlerts (per-metric)
  3. alert-log-muted-flag-dashboard — Add Muted field to AlertLogEntry, pass through RecordAlert
  4. alert-log-muted-flag-lite — Add muted column to DuckDB insert in EmailAlertService.LogAlertAsync

Phase 3: UI — Mute Rule Management

  1. dialog-mute-rule-dashboard — Create MuteRuleDialog.xaml/.cs for creating/editing rules
  2. dialog-mute-rule-lite — Create equivalent for Lite edition
  3. window-manage-rules-dashboard — Create ManageMuteRulesWindow (list, enable/disable, delete)
  4. window-manage-rules-lite — Create equivalent for Lite edition
  5. settings-button-dashboard — Add "Manage Mute Rules..." button to Dashboard SettingsWindow
  6. settings-button-lite — Add equivalent to Lite SettingsWindow

Phase 4: UI — Alert History Integration

  1. context-menu-dashboard — Add right-click "Mute" options to Dashboard alert history
  2. context-menu-lite — Add right-click "Mute" options to Lite AlertsHistoryTab
  3. visual-indicator-dashboard — Show muted alerts with distinct styling in alert history
  4. visual-indicator-lite — Same for Lite

Phase 5: MCP & Polish

  1. mcp-tools-dashboard — Add get_mute_rules to Dashboard McpAlertTools
  2. mcp-tools-lite — Add get_mute_rules to Lite McpAlertTools
  3. docs-readme — Update README alert section with mute rule documentation

Dependencies

  • Phase 2 depends on Phase 1
  • Phase 3 depends on Phase 1
  • Phase 4 depends on Phase 2 + Phase 3
  • Phase 5 depends on Phase 1

Notes

  • Match logic uses AND across non-null fields (all specified fields must match)
  • Instance-based muting is just a pattern rule with all fields populated from context
  • Expired rules are automatically skipped during matching and can be cleaned up periodically
  • Existing server silencing / acknowledgement / cooldown mechanisms remain unchanged
  • Muted alerts are still written to the alert log for auditability — they just don't trigger notifications
  • DuckDB schema version will need to be bumped for the Lite table changes

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions