Skip to content

Feature/alert muting part 2#642

Merged
erikdarlingdata merged 4 commits into
erikdarlingdata:devfrom
HannahVernon:feature/alert-muting-part-2
Mar 23, 2026
Merged

Feature/alert muting part 2#642
erikdarlingdata merged 4 commits into
erikdarlingdata:devfrom
HannahVernon:feature/alert-muting-part-2

Conversation

@HannahVernon
Copy link
Copy Markdown
Contributor

@HannahVernon HannahVernon commented Mar 19, 2026

What does this PR do?

Improves the Alert Muting feature by prefilling certain muting filter fields when adding a mute filter from the Alert History window. Automatically filled fields include the database name, the wait type, and query text. The filter fields available depend on the type of alert being muted; long-running-queries have different context than TempDB usage, for example. This PR also adds a configurable default expiration period for alerts.

Which component(s) does this affect?

  • [✔] Full Dashboard
  • [✔] Lite Dashboard
  • [] Lite Tests
  • [] SQL collection scripts
  • [] CLI Installer
  • [] GUI Installer
  • [] Documentation

How was this tested?

Tested on multiple SQL Server 2022 Enterprise and SQL Server 2019 VM-based instances inside and outside Azure.

Checklist

  • [✔] I have read the contributing guide
  • [✔] My code builds with zero warnings (dotnet build -c Debug)
  • [✔] I have tested my changes against at least one SQL Server version
  • [✔] I have not introduced any hardcoded credentials or server names

Summary by CodeRabbit

  • New Features

    • Configurable default expiration for new mute rules (1 hour, 24 hours, 7 days, Never); persisted in settings and applied when creating mutes.
    • Mute dialog now auto-populates additional context from an alert’s detail text (database, query text, wait type, job name) for improved matching.
    • Settings UI added to manage the mute-rule default.
    • Query pattern field includes a tooltip explaining case‑insensitive substring matching.
  • Bug Fixes

    • Multi-line text is flattened before truncation for consistent display.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 19, 2026

📝 Walkthrough

Walkthrough

Parses alert DetailText into AlertMuteContext (database/query/wait/job) before creating or matching mute rules, adds a user-configurable default expiration for new mute rules (UI, persistence, and dialog defaulting), and flattens multi-line text before truncation in MainWindow.

Changes

Cohort / File(s) Summary
User Preferences & Persistent Setting
Dashboard/Models/UserPreferences.cs, Lite/App.xaml.cs
Added MuteRuleDefaultExpiration defaulting to "24 hours"; Lite reads mute_rule_default_expiration from settings.json when the value is one of the allowed options.
Mute Rule Dialog Default Expiration
Dashboard/MuteRuleDialog.xaml.cs, Lite/Windows/MuteRuleDialog.xaml.cs
Added public static DefaultExpiration (Dashboard) and ApplyDefaultExpiration() (Lite) to set ExpirationCombo.SelectedIndex based on saved preference when creating a new rule.
Settings UI Controls
Dashboard/SettingsWindow.xaml, Lite/Windows/SettingsWindow.xaml
Inserted ComboBox x:Name="MuteRuleDefaultExpirationCombo" with options: 1 hour, 24 hours, 7 days, Never; adjusted Lite button margin for spacing.
Settings Load/Save & Restore Logic
Dashboard/SettingsWindow.xaml.cs, Lite/Windows/SettingsWindow.xaml.cs
Map combo selection ↔ preference strings, initialize combo from saved preference, restore defaults sets index for 24 hours, save preference back to settings and update dialog default.
Alert Mute Context Parsing
Dashboard/Models/MuteRule.cs, Lite/Models/MuteRule.cs
Added AlertMuteContext.PopulateFromDetailText(string? detailText) which parses newline-delimited, label-prefixed detail text and populates DatabaseName, QueryText, WaitType, and JobName when those properties are null; includes helpers to accumulate multi-line query text.
Alerts UI Integration
Dashboard/Controls/AlertsHistoryContent.xaml.cs, Lite/Controls/AlertsHistoryTab.xaml.cs
"Mute this alert" handlers now call context.PopulateFromDetailText(item.DetailText) after setting ServerName/MetricName and before showing the MuteRule dialog.
Startup & Misc UI Behavior
Dashboard/MainWindow.xaml.cs
MainWindow_Loaded applies MuteRuleDialog.DefaultExpiration from startup preferences; Truncate now replaces \r/\n with spaces before trimming to flatten multi-line text.
MuteRule Dialog XAML Help Text
Dashboard/MuteRuleDialog.xaml, Lite/Windows/MuteRuleDialog.xaml
Added ToolTip to QueryTextPatternBox describing case-insensitive substring matching; minor layout/row-index adjustments in Lite XAML.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Feature/alert muting part 2' is vague and generic, using non-descriptive terminology that does not clearly convey the main changes or purpose of this pull request to someone reviewing the project history. Consider a more specific title that highlights the primary features added, such as 'Auto-populate mute rule fields from alert details and add default expiration preference' or 'Improve alert muting with context pre-filling and configurable defaults'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dashboard/Models/MuteRule.cs`:
- Around line 102-119: The XML doc for PopulateFromDetailText claims it extracts
"Job Name" but the method only parses Database, Query and Wait Type; either
update the summary to remove "Job Name" or add parsing logic for the Job Name
field. To fix, locate the PopulateFromDetailText method and either (A) change
the XML summary to list the three fields actually parsed (Database, Query, Wait
Type), or (B) implement parsing for a "Job Name: " line by checking
trimmed.StartsWith("Job Name: ", StringComparison.Ordinal) and assigning the
value to the JobName property (matching how DatabaseName, QueryText and WaitType
are handled). Ensure you reference the DatabaseName, QueryText, WaitType and
JobName symbols consistently.

In `@Lite/Models/MuteRule.cs`:
- Around line 102-119: The XML doc for PopulateFromDetailText incorrectly claims
it extracts "Job Name" while the method only sets DatabaseName, QueryText, and
WaitType; either update the summary to remove "Job Name" or extend
PopulateFromDetailText to parse "Job Name: " lines by adding a branch similar to
the others (check trimmed.StartsWith("Job Name: ", StringComparison.Ordinal) and
assign the value to the JobName property), referencing the
PopulateFromDetailText method and the JobName, DatabaseName, QueryText, and
WaitType members when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4c533fa7-5cea-4f35-aa55-ad4c09488fe3

📥 Commits

Reviewing files that changed from the base of the PR and between ff43c28 and 0079dea.

📒 Files selected for processing (13)
  • Dashboard/Controls/AlertsHistoryContent.xaml.cs
  • Dashboard/MainWindow.xaml.cs
  • Dashboard/Models/MuteRule.cs
  • Dashboard/Models/UserPreferences.cs
  • Dashboard/MuteRuleDialog.xaml.cs
  • Dashboard/SettingsWindow.xaml
  • Dashboard/SettingsWindow.xaml.cs
  • Lite/App.xaml.cs
  • Lite/Controls/AlertsHistoryTab.xaml.cs
  • Lite/Models/MuteRule.cs
  • Lite/Windows/MuteRuleDialog.xaml.cs
  • Lite/Windows/SettingsWindow.xaml
  • Lite/Windows/SettingsWindow.xaml.cs

Comment thread Dashboard/Models/MuteRule.cs Outdated
Comment thread Lite/Models/MuteRule.cs Outdated
@HannahVernon
Copy link
Copy Markdown
Contributor Author

I'm just working through improving the query text being shown in the 'Query Text' Match Criteria in the 'Create Mute Rule' dialog box.

@HannahVernon
Copy link
Copy Markdown
Contributor Author

Pushed three follow-up commits addressing the review feedback and a bug found during testing:

1. Add missing Job Name parsing (fc9c5cd)

CodeRabbit flagged that the XML doc on PopulateFromDetailText claimed Job Name extraction but the parser didn't implement it. Added the missing "Job Name: " branch in both editions.

2. Fix mute dialog showing truncated query text (1376094)

When creating a mute rule from a blocking alert, the Query Text field only showed <?query instead of the full SQL text. Root cause: query text from blocked process reports contains newlines, and the line-by-line parser only captured the first line.

Fixes applied:

  • Truncate/TruncateText now collapse \r/\n to spaces before truncating, so detail text fields stay single-line
  • PopulateFromDetailText now accumulates multi-line continuation lines for query values (handles existing stored alerts)
  • Parser now recognizes variant query labels (Blocked Query, Blocking Query, Victim SQL) in addition to Query

3. Add tooltip to Query Text field (b09adae)

Added a tooltip to the Query Text input in the mute rule dialog explaining that it's a case-insensitive substring match, with guidance to enter a distinctive fragment like a table name or procedure call.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
Lite/Windows/MuteRuleDialog.xaml (2)

100-101: Wrap tooltip content for readability.

The new guidance is helpful; consider using a wrapped TextBlock tooltip so long text doesn’t render as a very wide single line.

Suggested tooltip formatting
-            <TextBox Grid.Row="3" Grid.Column="0" x:Name="QueryTextPatternBox" Margin="0,0,0,8"
-                     ToolTip="Alerts whose query text contains this value (case-insensitive) will be muted. Use a distinctive fragment such as a table name or procedure call."/>
+            <TextBox Grid.Row="3" Grid.Column="0" x:Name="QueryTextPatternBox" Margin="0,0,0,8">
+                <TextBox.ToolTip>
+                    <TextBlock MaxWidth="320"
+                               TextWrapping="Wrap"
+                               Text="Alerts whose query text contains this value (case-insensitive) will be muted. Use a distinctive fragment such as a table name or procedure call."/>
+                </TextBox.ToolTip>
+            </TextBox>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Lite/Windows/MuteRuleDialog.xaml` around lines 100 - 101, The Tooltip on
QueryTextPatternBox currently uses a plain string which renders as one long
line; change it to a wrapped TextBlock so the tooltip wraps and limits width for
readability by replacing the ToolTip attribute on QueryTextPatternBox with a
ToolTip element containing a TextBlock (set TextWrapping="Wrap" and a reasonable
MaxWidth, e.g., 300) and move the long guidance text into that TextBlock; update
the XAML for the QueryTextPatternBox control accordingly.

45-50: Avoid hardcoded SelectedIndex for expiration defaults.

Line 45 hardcodes SelectedIndex="3" (Never (permanent)), which can drift from the configurable default and from future item reordering. Prefer letting code-behind set the initial selection explicitly (with a safe fallback).

Suggested XAML adjustment
-        <ComboBox Grid.Row="5" x:Name="ExpirationCombo" SelectedIndex="3" Margin="0,0,0,12">
+        <ComboBox Grid.Row="5" x:Name="ExpirationCombo" Margin="0,0,0,12">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Lite/Windows/MuteRuleDialog.xaml` around lines 45 - 50, Remove the hardcoded
SelectedIndex="3" from the ExpirationCombo XAML and instead set the initial
selection in the MuteRuleDialog code-behind (e.g., in the MuteRuleDialog
constructor or Loaded handler). Read the configured/default expiration value (or
index) from the existing settings API, map it to an ExpirationCombo item (by
index or by matching ComboBoxItem.Content), and set
ExpirationCombo.SelectedIndex with a safe fallback (e.g., if configured index is
out of range, choose the last item or a sensible default). Ensure this uses the
ExpirationCombo control name so future reordering of XAML items won’t break the
default.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Lite/Windows/MuteRuleDialog.xaml`:
- Around line 100-101: The Tooltip on QueryTextPatternBox currently uses a plain
string which renders as one long line; change it to a wrapped TextBlock so the
tooltip wraps and limits width for readability by replacing the ToolTip
attribute on QueryTextPatternBox with a ToolTip element containing a TextBlock
(set TextWrapping="Wrap" and a reasonable MaxWidth, e.g., 300) and move the long
guidance text into that TextBlock; update the XAML for the QueryTextPatternBox
control accordingly.
- Around line 45-50: Remove the hardcoded SelectedIndex="3" from the
ExpirationCombo XAML and instead set the initial selection in the MuteRuleDialog
code-behind (e.g., in the MuteRuleDialog constructor or Loaded handler). Read
the configured/default expiration value (or index) from the existing settings
API, map it to an ExpirationCombo item (by index or by matching
ComboBoxItem.Content), and set ExpirationCombo.SelectedIndex with a safe
fallback (e.g., if configured index is out of range, choose the last item or a
sensible default). Ensure this uses the ExpirationCombo control name so future
reordering of XAML items won’t break the default.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5103dbd7-7f34-4a51-b217-b3f29798a421

📥 Commits

Reviewing files that changed from the base of the PR and between 1376094 and b09adae.

📒 Files selected for processing (2)
  • Dashboard/MuteRuleDialog.xaml
  • Lite/Windows/MuteRuleDialog.xaml
✅ Files skipped from review due to trivial changes (1)
  • Dashboard/MuteRuleDialog.xaml

@erikdarlingdata
Copy link
Copy Markdown
Owner

Hey @HannahVernon — this has merge conflicts with dev after the recent Velopack integration, data directory migration, and time slicer PRs. Could you rebase onto current dev when you get a chance? The conflicting files are mostly App.xaml.cs, MainWindow.xaml.cs, and SettingsWindow.xaml. Thanks!

HannahVernon and others added 4 commits March 23, 2026 10:51
- Parse detail_text to extract Database, Query Text, and Wait Type
  when using 'Mute This Alert' from alert history (both editions)
- Add PopulateFromDetailText() to AlertMuteContext for structured
  field extraction from the label: value format
- Add 'Default expiration for new mute rules' dropdown to Settings
  in both editions (1 hour, 24 hours, 7 days, Never; default 24h)
- MuteRuleDialog now selects the configured default expiration
  instead of always defaulting to 'Never'
- Persist setting as mute_rule_default_expiration in settings.json
  (Lite) and preferences.json (Dashboard)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The XML doc claimed Job Name extraction but the parser did not
implement it. Add the missing branch in both Dashboard and Lite
editions so the behavior matches the documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Collapse newlines in Truncate/TruncateText so detail_text fields
  stay single-line in the label: value format
- Handle multi-line query values in PopulateFromDetailText by
  accumulating continuation lines until the next indented field
- Recognize variant query labels (Blocked Query, Blocking Query,
  Victim SQL) in addition to Query

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Explain that the field is a case-insensitive substring match and
suggest entering a distinctive fragment like a table or procedure name.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@HannahVernon HannahVernon force-pushed the feature/alert-muting-part-2 branch from b09adae to b711025 Compare March 23, 2026 17:27
@HannahVernon
Copy link
Copy Markdown
Contributor Author

@erikdarlingdata - rebased 👍

@erikdarlingdata erikdarlingdata merged commit 827b078 into erikdarlingdata:dev Mar 23, 2026
3 checks passed
@erikdarlingdata erikdarlingdata mentioned this pull request Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants