Skip to content

Commit 6e89337

Browse files
Default trace overhaul, memory clerks picker, memory grants fix, query trace plan support
Default trace collector: add ErrorLog, Object DDL, Security Audit event types; add duration_us and end_time columns for autogrow I/O stall tracking; filter autogrow to > 1s duration only; exclude tempdb Object DDL and auto-stats (_WA_%). Remove redundant Trace Analysis tab (superseded by Query Trace Patterns). Dashboard memory clerks: add type picker with search, top-N, select/clear-all (parity with Lite). Memory grants: remove granted_memory_mb > 0 filter in both Dashboard and Lite that hid data when no active grants existed. Query Trace Patterns: wire up Get Actual Plan for LongRunningQueryPatternItem using full SampleQueryText (removed artificial 500-char truncation). View Estimated Plan shows helpful redirect message. Includes upgrade script (03_default_trace_schema.sql) for 1.3.0-to-2.0.0. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 975466c commit 6e89337

16 files changed

Lines changed: 571 additions & 311 deletions

Dashboard/Controls/DefaultTraceContent.xaml

Lines changed: 74 additions & 128 deletions
Large diffs are not rendered by default.

Dashboard/Controls/DefaultTraceContent.xaml.cs

Lines changed: 8 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,13 @@ public partial class DefaultTraceContent : UserControl
2828
private DateTime? _defaultTraceEventsToDate;
2929
private string? _defaultTraceEventsFilter;
3030

31-
private int _traceAnalysisHoursBack = 24;
32-
private DateTime? _traceAnalysisFromDate;
33-
private DateTime? _traceAnalysisToDate;
34-
35-
// Popup filter state (shared popup, per-grid filter dictionaries)
31+
// Popup filter state
3632
private Popup? _filterPopup;
3733
private ColumnFilterPopup? _filterPopupContent;
38-
private string? _activeFilterGrid;
3934

4035
private readonly Dictionary<string, ColumnFilterState> _defaultTraceFilters = new();
4136
private List<DefaultTraceEventItem>? _defaultTraceUnfilteredData;
4237

43-
private readonly Dictionary<string, ColumnFilterState> _traceAnalysisFilters = new();
44-
private List<TraceAnalysisItem>? _traceAnalysisUnfilteredData;
45-
4638
public DefaultTraceContent()
4739
{
4840
InitializeComponent();
@@ -58,28 +50,19 @@ public void SetTimeRange(int hoursBack, DateTime? fromDate = null, DateTime? toD
5850
_defaultTraceEventsHoursBack = hoursBack;
5951
_defaultTraceEventsFromDate = fromDate;
6052
_defaultTraceEventsToDate = toDate;
61-
62-
_traceAnalysisHoursBack = hoursBack;
63-
_traceAnalysisFromDate = fromDate;
64-
_traceAnalysisToDate = toDate;
6553
}
6654

6755
public async Task RefreshAllDataAsync()
6856
{
6957
if (_databaseService == null) return;
7058

71-
await Task.WhenAll(
72-
RefreshDefaultTraceEventsAsync(),
73-
RefreshTraceAnalysisAsync()
74-
);
59+
await RefreshDefaultTraceEventsAsync();
7560
}
7661

7762
private void OnLoaded(object sender, RoutedEventArgs e)
7863
{
7964
TabHelpers.AutoSizeColumnMinWidths(DefaultTraceEventsDataGrid);
80-
TabHelpers.AutoSizeColumnMinWidths(TraceAnalysisDataGrid);
8165
TabHelpers.FreezeColumns(DefaultTraceEventsDataGrid, 1);
82-
TabHelpers.FreezeColumns(TraceAnalysisDataGrid, 1);
8366
}
8467

8568
#region Default Trace Events
@@ -130,45 +113,14 @@ private async Task RefreshDefaultTraceEventsAsync()
130113

131114
#endregion
132115

133-
#region Trace Analysis
134-
135-
private async Task RefreshTraceAnalysisAsync()
136-
{
137-
if (_databaseService == null) return;
138-
139-
try
140-
{
141-
var data = await _databaseService.GetTraceAnalysisAsync(_traceAnalysisHoursBack, _traceAnalysisFromDate, _traceAnalysisToDate);
142-
_traceAnalysisUnfilteredData = data;
143-
_traceAnalysisFilters.Clear();
144-
TraceAnalysisDataGrid.ItemsSource = data;
145-
TraceAnalysisNoDataMessage.Visibility = data.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
146-
UpdateFilterButtonStyles(TraceAnalysisDataGrid, _traceAnalysisFilters);
147-
}
148-
catch (Exception ex)
149-
{
150-
Logger.Error($"Error loading trace analysis: {ex.Message}");
151-
}
152-
}
153-
154-
#endregion
155-
156116
#region Popup Filter Infrastructure
157117

158118
private void DefaultTraceFilter_Click(object sender, RoutedEventArgs e)
159119
{
160-
_activeFilterGrid = "DefaultTrace";
161120
if (sender is Button button && button.Tag is string columnName)
162121
ShowFilterPopup(button, columnName, _defaultTraceFilters);
163122
}
164123

165-
private void TraceAnalysisFilter_Click(object sender, RoutedEventArgs e)
166-
{
167-
_activeFilterGrid = "TraceAnalysis";
168-
if (sender is Button button && button.Tag is string columnName)
169-
ShowFilterPopup(button, columnName, _traceAnalysisFilters);
170-
}
171-
172124
private void ShowFilterPopup(Button button, string columnName, Dictionary<string, ColumnFilterState> filters)
173125
{
174126
if (_filterPopup == null)
@@ -197,26 +149,12 @@ private void FilterPopup_FilterApplied(object? sender, FilterAppliedEventArgs e)
197149
if (_filterPopup != null)
198150
_filterPopup.IsOpen = false;
199151

200-
switch (_activeFilterGrid)
201-
{
202-
case "DefaultTrace":
203-
if (e.FilterState.IsActive)
204-
_defaultTraceFilters[e.FilterState.ColumnName] = e.FilterState;
205-
else
206-
_defaultTraceFilters.Remove(e.FilterState.ColumnName);
207-
ApplyFilters(_defaultTraceFilters, _defaultTraceUnfilteredData, DefaultTraceEventsDataGrid, DefaultTraceEventsNoDataMessage);
208-
UpdateFilterButtonStyles(DefaultTraceEventsDataGrid, _defaultTraceFilters);
209-
break;
210-
211-
case "TraceAnalysis":
212-
if (e.FilterState.IsActive)
213-
_traceAnalysisFilters[e.FilterState.ColumnName] = e.FilterState;
214-
else
215-
_traceAnalysisFilters.Remove(e.FilterState.ColumnName);
216-
ApplyFilters(_traceAnalysisFilters, _traceAnalysisUnfilteredData, TraceAnalysisDataGrid, TraceAnalysisNoDataMessage);
217-
UpdateFilterButtonStyles(TraceAnalysisDataGrid, _traceAnalysisFilters);
218-
break;
219-
}
152+
if (e.FilterState.IsActive)
153+
_defaultTraceFilters[e.FilterState.ColumnName] = e.FilterState;
154+
else
155+
_defaultTraceFilters.Remove(e.FilterState.ColumnName);
156+
ApplyFilters(_defaultTraceFilters, _defaultTraceUnfilteredData, DefaultTraceEventsDataGrid, DefaultTraceEventsNoDataMessage);
157+
UpdateFilterButtonStyles(DefaultTraceEventsDataGrid, _defaultTraceFilters);
220158
}
221159

222160
private void FilterPopup_FilterCleared(object? sender, EventArgs e)

Dashboard/Controls/MemoryContent.xaml

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -133,28 +133,66 @@
133133

134134
<!-- Memory Clerks Sub-Tab -->
135135
<TabItem Header="Memory Clerks">
136-
<!-- Chart + Summary Panel (grid removed) -->
137136
<Border BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Margin="5">
138137
<Grid>
139-
<Grid.RowDefinitions>
140-
<RowDefinition Height="Auto"/>
141-
<RowDefinition Height="*"/>
142-
<RowDefinition Height="Auto"/>
143-
</Grid.RowDefinitions>
144-
<TextBlock Grid.Row="0" Text="Top Memory Clerks Over Time" FontWeight="Bold" FontSize="14" Margin="10,5" Foreground="{DynamicResource ForegroundBrush}"/>
145-
<ScottPlot:WpfPlot Grid.Row="1" x:Name="MemoryClerksChart"/>
146-
<!-- Summary Panel (excludes buffer pool) -->
147-
<Border Grid.Row="2" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Padding="10,8">
148-
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
149-
<TextBlock Text="Non-BP Total:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
150-
<TextBlock x:Name="MemoryClerksTotalText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center" Margin="0,0,20,0"/>
151-
<TextBlock Text="Top Non-BP Clerk:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
152-
<TextBlock x:Name="MemoryClerksTopText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
153-
</StackPanel>
138+
<Grid.ColumnDefinitions>
139+
<ColumnDefinition Width="220"/>
140+
<ColumnDefinition Width="*"/>
141+
</Grid.ColumnDefinitions>
142+
143+
<!-- Clerk Type Picker -->
144+
<Border Grid.Column="0" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,0,1,0" Padding="8">
145+
<Grid>
146+
<Grid.RowDefinitions>
147+
<RowDefinition Height="Auto"/>
148+
<RowDefinition Height="Auto"/>
149+
<RowDefinition Height="Auto"/>
150+
<RowDefinition Height="*"/>
151+
</Grid.RowDefinitions>
152+
<TextBlock Grid.Row="0" Text="Select Memory Clerks" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundBrush}" Margin="0,0,0,4"/>
153+
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,4">
154+
<Button Content="Top Clerks" Click="MemoryClerkSelectTop_Click" Padding="6,2" Margin="0,0,4,0" FontSize="11"/>
155+
<Button Content="Clear All" Click="MemoryClerkClearAll_Click" Padding="6,2" FontSize="11"/>
156+
<TextBlock x:Name="MemoryClerkCountText" Text="0 selected" FontSize="10" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="8,0,0,0"/>
157+
</StackPanel>
158+
<TextBox Grid.Row="2" x:Name="MemoryClerkSearchBox" TextChanged="MemoryClerkSearch_TextChanged"
159+
Margin="0,0,0,4" Padding="4,2"/>
160+
<ListBox Grid.Row="3" x:Name="MemoryClerksList" Background="Transparent" BorderThickness="0">
161+
<ListBox.ItemTemplate>
162+
<DataTemplate>
163+
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}"
164+
Checked="MemoryClerk_CheckChanged" Unchecked="MemoryClerk_CheckChanged"
165+
Foreground="{DynamicResource ForegroundBrush}" FontSize="11">
166+
<TextBlock Text="{Binding DisplayName}"/>
167+
</CheckBox>
168+
</DataTemplate>
169+
</ListBox.ItemTemplate>
170+
</ListBox>
171+
</Grid>
154172
</Border>
155-
<TextBlock x:Name="MemoryClerksNoDataMessage" Grid.Row="1" Style="{StaticResource EmptyStateMessage}"
156-
Text="No memory clerk data in selected time range"/>
157-
<controls:LoadingOverlay x:Name="MemoryClerksLoading" Grid.Row="1"/>
173+
174+
<!-- Chart + Summary -->
175+
<Grid Grid.Column="1">
176+
<Grid.RowDefinitions>
177+
<RowDefinition Height="Auto"/>
178+
<RowDefinition Height="*"/>
179+
<RowDefinition Height="Auto"/>
180+
</Grid.RowDefinitions>
181+
<TextBlock Grid.Row="0" Text="Memory Clerks Over Time" FontWeight="Bold" FontSize="14" Margin="10,5" Foreground="{DynamicResource ForegroundBrush}"/>
182+
<ScottPlot:WpfPlot Grid.Row="1" x:Name="MemoryClerksChart"/>
183+
<!-- Summary Panel (excludes buffer pool) -->
184+
<Border Grid.Row="2" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Padding="10,8">
185+
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
186+
<TextBlock Text="Non-BP Total:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
187+
<TextBlock x:Name="MemoryClerksTotalText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center" Margin="0,0,20,0"/>
188+
<TextBlock Text="Top Non-BP Clerk:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
189+
<TextBlock x:Name="MemoryClerksTopText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
190+
</StackPanel>
191+
</Border>
192+
<TextBlock x:Name="MemoryClerksNoDataMessage" Grid.Row="1" Style="{StaticResource EmptyStateMessage}"
193+
Text="No memory clerk data in selected time range"/>
194+
<controls:LoadingOverlay x:Name="MemoryClerksLoading" Grid.Row="1"/>
195+
</Grid>
158196
</Grid>
159197
</Border>
160198
</TabItem>

0 commit comments

Comments
 (0)