Skip to content

Commit cb47ba2

Browse files
Merge pull request #810 from erikdarlingdata/dev
Release v2.6.0
2 parents e4580c7 + 6f103c3 commit cb47ba2

100 files changed

Lines changed: 8959 additions & 1947 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ jobs:
114114
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
115115
organization-id: '7969f8b6-d946-4a74-9bac-a55856d8b8e0'
116116
project-slug: 'PerformanceMonitor'
117-
signing-policy-slug: 'test-signing'
117+
signing-policy-slug: 'release-signing'
118118
artifact-configuration-slug: 'Dashboard'
119119
github-artifact-id: '${{ steps.upload-dashboard.outputs.artifact-id }}'
120120
wait-for-completion: true
@@ -127,7 +127,7 @@ jobs:
127127
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
128128
organization-id: '7969f8b6-d946-4a74-9bac-a55856d8b8e0'
129129
project-slug: 'PerformanceMonitor'
130-
signing-policy-slug: 'test-signing'
130+
signing-policy-slug: 'release-signing'
131131
artifact-configuration-slug: 'Lite'
132132
github-artifact-id: '${{ steps.upload-lite.outputs.artifact-id }}'
133133
wait-for-completion: true
@@ -140,7 +140,7 @@ jobs:
140140
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
141141
organization-id: '7969f8b6-d946-4a74-9bac-a55856d8b8e0'
142142
project-slug: 'PerformanceMonitor'
143-
signing-policy-slug: 'test-signing'
143+
signing-policy-slug: 'release-signing'
144144
artifact-configuration-slug: 'Installers'
145145
github-artifact-id: '${{ steps.upload-installer.outputs.artifact-id }}'
146146
wait-for-completion: true

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,6 @@ nul
5656
Lite/config/servers.json
5757
Lite/servers.json
5858
Lite/collection_schedule.json
59+
60+
# Plans directory
61+
plans/

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,51 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.6.0] - 2026-04-08
9+
10+
### Added
11+
12+
- **Correlated timeline lanes** on Lite Overview and Dashboard — synchronized CPU, memory, waits, and TempDB trend lanes for at-a-glance correlation ([#688])
13+
- **Dynamic baselines and anomaly detection** in Lite and Dashboard — automatic baseline calculation with anomaly highlighting on key metrics ([#692], [#693])
14+
- **Query grid comparison** — before/after comparison mode for query grids in Lite and Dashboard with global Compare dropdown ([#687])
15+
- **Nonclustered index count badge** on modification operators in plan viewer ([#788])
16+
- **Upgrade detection in Edit Server** dialog — see pending upgrades without adding a new server ([#772])
17+
- **CLI installer interactive mode** prompts for trust-cert and encryption settings ([#784])
18+
- **SignPath code signing** — release binaries are now digitally signed via the [SignPath FOSS](https://signpath.io) program
19+
20+
### Changed
21+
22+
- **PlanAnalyzer Rule 3 (Serial Plan)** comprehensively refined — severity demotion for TRIVIAL and 0ms plans, `CouldNotGenerateValidParallelPlan` treated as actionable, all 25 `NonParallelPlanReason` values now covered
23+
- **PlanAnalyzer warning rules** ported from PerformanceStudio improvements
24+
- **Text readability** — replaced all muted/dim text colors with full foreground colors for readability
25+
26+
### Fixed
27+
28+
- **Embedded resource upgrade discovery** broken — upgrades silently returned zero results for Dashboard installs ([#772])
29+
- **Archive compaction OOM** on large parquet groups
30+
- **CLI installer argument parsing** treating flags as positional args ([#786])
31+
- **Lite long-running query alerts** firing on stale DuckDB snapshots
32+
- **FinOps Enterprise feature detection** now queries all databases and filters to TDE only ([#780])
33+
- **Second launch error** — now brings existing window to foreground instead ([#769])
34+
- **Overview tab Memory Grant** showing 0 for all timestamps ([#776])
35+
- **Lite FinOps Enterprise features** query error on servers without `database_id` column ([#777])
36+
- **Collector health status** incorrect for on-load collectors
37+
- **CSV and clipboard exports** writing `System.Windows.Controls.StackPanel` as column headers instead of actual header text ([#805])
38+
39+
[#687]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/687
40+
[#688]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/688
41+
[#692]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/692
42+
[#693]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/693
43+
[#769]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/769
44+
[#772]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/772
45+
[#776]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/776
46+
[#777]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/777
47+
[#780]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/780
48+
[#784]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/784
49+
[#786]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/786
50+
[#788]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/788
51+
[#805]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/805
52+
853
## [2.5.0] - 2026-03-30
954

1055
### Important

Dashboard/AddServerDialog.xaml

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,26 @@
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
Title="Add SQL Server"
5-
SizeToContent="Height" Width="500" MaxHeight="1050"
5+
Height="750" Width="500"
66
WindowStartupLocation="CenterOwner"
7-
ResizeMode="NoResize"
7+
ResizeMode="CanResizeWithGrip"
88
Background="{DynamicResource BackgroundBrush}"
99
Foreground="{DynamicResource ForegroundBrush}">
10-
<ScrollViewer VerticalScrollBarVisibility="Auto">
11-
<Grid Margin="20">
10+
<Grid Margin="20">
11+
<Grid.RowDefinitions>
12+
<RowDefinition Height="*"/>
13+
<RowDefinition Height="Auto"/>
14+
</Grid.RowDefinitions>
15+
16+
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto">
17+
<Grid>
1218
<Grid.RowDefinitions>
1319
<RowDefinition Height="Auto"/>
1420
<RowDefinition Height="Auto"/>
1521
<RowDefinition Height="Auto"/>
1622
<RowDefinition Height="Auto"/>
1723
<RowDefinition Height="Auto"/>
1824
<RowDefinition Height="Auto"/>
19-
<RowDefinition Height="Auto"/>
2025
</Grid.RowDefinitions>
2126

2227
<!-- Header -->
@@ -217,14 +222,17 @@
217222
Foreground="{DynamicResource ForegroundMutedBrush}"
218223
TextWrapping="Wrap" Margin="0,8,0,0" Visibility="Collapsed"/>
219224

220-
<!-- Buttons -->
221-
<StackPanel Grid.Row="6" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,15,0,0">
222-
<Button x:Name="ViewReportButton" Content="View Report" Margin="0,0,8,0"
223-
Click="ViewReport_Click" Visibility="Collapsed"/>
224-
<Button x:Name="TestConnectionButton" Content="Test Connection" Margin="0,0,8,0" Click="TestConnection_Click"/>
225-
<Button x:Name="SaveButton" Content="Save" MinWidth="80" Height="30" Padding="12,0" Margin="0,0,10,0" Click="Save_Click" IsDefault="True" Style="{StaticResource AccentButton}"/>
226-
<Button Content="Cancel" Width="80" Height="30" Click="Cancel_Click" IsCancel="True"/>
227-
</StackPanel>
228225
</Grid>
229-
</ScrollViewer>
226+
</ScrollViewer>
227+
228+
<!-- Buttons pinned to bottom -->
229+
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,15,0,0">
230+
<Button x:Name="ViewReportButton" Content="View Report" Margin="0,0,8,0"
231+
Click="ViewReport_Click" Visibility="Collapsed"/>
232+
<Button x:Name="CheckForUpdatesButton" Content="Check for Updates" Margin="0,0,8,0" Click="CheckForUpdates_Click"/>
233+
<Button x:Name="TestConnectionButton" Content="Test Connection" Margin="0,0,8,0" Click="TestConnection_Click"/>
234+
<Button x:Name="SaveButton" Content="Save" MinWidth="80" Height="30" Padding="12,0" Margin="0,0,10,0" Click="Save_Click" IsDefault="True" Style="{StaticResource AccentButton}"/>
235+
<Button Content="Cancel" Width="80" Height="30" Click="Cancel_Click" IsCancel="True"/>
236+
</StackPanel>
237+
</Grid>
230238
</Window>

Dashboard/AddServerDialog.xaml.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,24 @@ happens after the connection test in DetectDatabaseStatusAsync() */
313313
return (connected, errorMessage, mfaCancelled, serverVersion);
314314
}
315315

316+
private async void CheckForUpdates_Click(object sender, RoutedEventArgs e)
317+
{
318+
if (!ValidateInputs()) return;
319+
320+
CheckForUpdatesButton.IsEnabled = false;
321+
CheckForUpdatesButton.Content = "Checking...";
322+
323+
try
324+
{
325+
await DetectDatabaseStatusAsync();
326+
}
327+
finally
328+
{
329+
CheckForUpdatesButton.IsEnabled = true;
330+
CheckForUpdatesButton.Content = "Check for Updates";
331+
}
332+
}
333+
316334
private async void TestConnection_Click(object sender, RoutedEventArgs e)
317335
{
318336
if (!ValidateInputs()) return;
@@ -331,11 +349,8 @@ private async void TestConnection_Click(object sender, RoutedEventArgs e)
331349
MessageBoxImage.Information
332350
);
333351

334-
/* After successful connection in Add mode, check database status */
335-
if (!_isEditMode)
336-
{
337-
await DetectDatabaseStatusAsync();
338-
}
352+
/* After successful connection, check database status */
353+
await DetectDatabaseStatusAsync();
339354
}
340355
else if (mfaCancelled)
341356
{

Dashboard/Analysis/AnalysisService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class AnalysisService
2323
private readonly InferenceEngine _engine;
2424
private readonly SqlServerDrillDownCollector _drillDown;
2525
private readonly SqlServerAnomalyDetector _anomalyDetector;
26+
private readonly SqlServerBaselineProvider _baselineProvider;
2627

2728
/// <summary>
2829
/// Minimum hours of collected data required before analysis will run.
@@ -60,7 +61,8 @@ public AnalysisService(string connectionString, IPlanFetcher? planFetcher = null
6061
_graph = new RelationshipGraph();
6162
_engine = new InferenceEngine(_graph);
6263
_drillDown = new SqlServerDrillDownCollector(connectionString, planFetcher);
63-
_anomalyDetector = new SqlServerAnomalyDetector(connectionString);
64+
_baselineProvider = new SqlServerBaselineProvider(connectionString);
65+
_anomalyDetector = new SqlServerAnomalyDetector(connectionString, _baselineProvider);
6466
}
6567

6668
/// <summary>

Dashboard/Analysis/FactScorer.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,12 @@ private static double ScoreBadActorFact(Fact fact)
308308
/// </summary>
309309
private static double ScoreAnomalyFact(Fact fact)
310310
{
311-
if ( fact.Key.StartsWith("ANOMALY_CPU_SPIKE" , StringComparison.OrdinalIgnoreCase)
312-
|| fact.Key.StartsWith("ANOMALY_READ_LATENCY" , StringComparison.OrdinalIgnoreCase)
313-
|| fact.Key.StartsWith("ANOMALY_WRITE_LATENCY", StringComparison.OrdinalIgnoreCase)
311+
if ( fact.Key.StartsWith("ANOMALY_CPU_SPIKE" , StringComparison.OrdinalIgnoreCase)
312+
|| fact.Key.StartsWith("ANOMALY_READ_LATENCY" , StringComparison.OrdinalIgnoreCase)
313+
|| fact.Key.StartsWith("ANOMALY_WRITE_LATENCY" , StringComparison.OrdinalIgnoreCase)
314+
|| fact.Key.StartsWith("ANOMALY_BATCH_REQUESTS", StringComparison.OrdinalIgnoreCase)
315+
|| fact.Key.StartsWith("ANOMALY_SESSION_SPIKE" , StringComparison.OrdinalIgnoreCase)
316+
|| fact.Key.StartsWith("ANOMALY_QUERY_DURATION", StringComparison.OrdinalIgnoreCase)
314317
)
315318
{
316319
// Deviation-based scoring: 2σ = 0.5, 4σ = 1.0

0 commit comments

Comments
 (0)