Which component(s) does this affect?
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
Dashboard — EvaluateAlertConditionsAsync() 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
Lite — CheckPerformanceAlerts() 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
- model-mute-rule — Create
MuteRule model class (both editions)
- service-mute-rule-dashboard — Create
MuteRuleService for Dashboard (JSON persistence, match logic)
- service-mute-rule-lite — Create
MuteRuleService for Lite (DuckDB persistence, match logic)
- lite-schema-update — Add
config_mute_rules table + muted column to config_alert_log in Schema.cs
Phase 2: Alert Pipeline Integration
- integrate-dashboard-eval — Wire mute checks into
EvaluateAlertConditionsAsync (per-metric)
- integrate-lite-eval — Wire mute checks into
CheckPerformanceAlerts (per-metric)
- alert-log-muted-flag-dashboard — Add
Muted field to AlertLogEntry, pass through RecordAlert
- alert-log-muted-flag-lite — Add
muted column to DuckDB insert in EmailAlertService.LogAlertAsync
Phase 3: UI — Mute Rule Management
- dialog-mute-rule-dashboard — Create
MuteRuleDialog.xaml/.cs for creating/editing rules
- dialog-mute-rule-lite — Create equivalent for Lite edition
- window-manage-rules-dashboard — Create
ManageMuteRulesWindow (list, enable/disable, delete)
- window-manage-rules-lite — Create equivalent for Lite edition
- settings-button-dashboard — Add "Manage Mute Rules..." button to Dashboard SettingsWindow
- settings-button-lite — Add equivalent to Lite SettingsWindow
Phase 4: UI — Alert History Integration
- context-menu-dashboard — Add right-click "Mute" options to Dashboard alert history
- context-menu-lite — Add right-click "Mute" options to Lite AlertsHistoryTab
- visual-indicator-dashboard — Show muted alerts with distinct styling in alert history
- visual-indicator-lite — Same for Lite
Phase 5: MCP & Polish
- mcp-tools-dashboard — Add
get_mute_rules to Dashboard McpAlertTools
- mcp-tools-lite — Add
get_mute_rules to Lite McpAlertTools
- 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
Which component(s) does this affect?
Problem Statement
Users cannot suppress specific recurring alerts. The only existing options are coarse-grained:
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
mutedflag) but suppressed from tray notifications, emails, and UI badges.Two muting modes:
Data Model
Alert Context for Matching
Integration Points
Dashboard —
EvaluateAlertConditionsAsync()in MainWindow.xaml.cs:_muteRuleService.IsAlertMuted(context)with available detailMuted=true, skip tray/email/badgeLite —
CheckPerformanceAlerts()in MainWindow.xaml.cs:muted=TRUE, skip tray/emailPersistence
Dashboard:
alert_mute_rules.jsonin%APPDATA%\PerformanceMonitorDashboard\Lite: New DuckDB table
config_mute_rulesUI
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
MuteRulemodel class (both editions)MuteRuleServicefor Dashboard (JSON persistence, match logic)MuteRuleServicefor Lite (DuckDB persistence, match logic)config_mute_rulestable +mutedcolumn toconfig_alert_login Schema.csPhase 2: Alert Pipeline Integration
EvaluateAlertConditionsAsync(per-metric)CheckPerformanceAlerts(per-metric)Mutedfield toAlertLogEntry, pass throughRecordAlertmutedcolumn to DuckDB insert inEmailAlertService.LogAlertAsyncPhase 3: UI — Mute Rule Management
MuteRuleDialog.xaml/.csfor creating/editing rulesManageMuteRulesWindow(list, enable/disable, delete)Phase 4: UI — Alert History Integration
Phase 5: MCP & Polish
get_mute_rulesto Dashboard McpAlertToolsget_mute_rulesto Lite McpAlertToolsDependencies
Notes