Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
7601aab
README: add shields.io badge flair (repo + social)
erikdarlingdata Mar 31, 2026
5d344a9
Merge pull request #770 from erikdarlingdata/feature/readme-badges
erikdarlingdata Mar 31, 2026
79d5bc6
Enable upgrade detection in Edit Server dialog
erikdarlingdata Apr 1, 2026
0fa1389
Merge pull request #773 from erikdarlingdata/feature/edit-server-upgr…
erikdarlingdata Apr 1, 2026
c77e970
Fix embedded resource upgrade discovery and add server version UX (#772)
erikdarlingdata Apr 1, 2026
5fcc598
Merge pull request #774 from erikdarlingdata/fix/772-embedded-upgrade…
erikdarlingdata Apr 1, 2026
ef2ef7e
Fix Lite FinOps Enterprise features query for servers without databas…
erikdarlingdata Apr 2, 2026
3c46528
Merge pull request #778 from erikdarlingdata/fix/777-lite-sku-feature…
erikdarlingdata Apr 2, 2026
9f2f63d
Fix Overview tab showing Memory Grant as 0 for all timestamps
erikdarlingdata Apr 2, 2026
10f8bfb
Merge pull request #779 from erikdarlingdata/fix/776-overview-memory-…
erikdarlingdata Apr 2, 2026
b012a13
Bring existing window to foreground on second launch instead of error
erikdarlingdata Apr 2, 2026
3efa63b
Merge pull request #781 from erikdarlingdata/fix/769-bring-to-foreground
erikdarlingdata Apr 2, 2026
bd061f6
Fix FinOps Enterprise feature detection: query all databases, filter …
erikdarlingdata Apr 2, 2026
0f2de62
Merge pull request #782 from erikdarlingdata/fix/780-finops-enterpris…
erikdarlingdata Apr 2, 2026
0b11df5
Fix Lite long-running query alerts firing on stale DuckDB snapshots
erikdarlingdata Apr 2, 2026
49af520
Merge pull request #783 from erikdarlingdata/fix/lite-stale-snapshot-…
erikdarlingdata Apr 2, 2026
91d00f6
Add trust-cert and encryption prompts to CLI installer interactive mode
erikdarlingdata Apr 3, 2026
38e6363
Merge pull request #785 from erikdarlingdata/fix/784-interactive-mode…
erikdarlingdata Apr 3, 2026
3ad2908
Fix CLI installer argument parsing treating flags as positional args
erikdarlingdata Apr 4, 2026
77f8f6e
Merge pull request #787 from erikdarlingdata/fix/786-installer-arg-pa…
erikdarlingdata Apr 4, 2026
6afaef6
Add plans/ directory to .gitignore
erikdarlingdata Apr 6, 2026
ea24c35
Merge pull request #789 from erikdarlingdata/gitignore-plans
erikdarlingdata Apr 6, 2026
1bfabb4
Show nonclustered index count badge on modification operators in plan…
erikdarlingdata Apr 6, 2026
718117a
Merge pull request #790 from erikdarlingdata/issue-788-nci-badge
erikdarlingdata Apr 6, 2026
1b05bae
Add correlated timeline lanes to Lite Overview tab (#688)
erikdarlingdata Apr 6, 2026
b6c9f3e
Port correlated timeline lanes to Dashboard (#688)
erikdarlingdata Apr 6, 2026
07ed478
Merge dev into feature/correlated-timeline-lanes
erikdarlingdata Apr 6, 2026
c6487f7
Merge pull request #791 from erikdarlingdata/feature/correlated-timel…
erikdarlingdata Apr 6, 2026
750c0b9
Fix archive compaction OOM on large parquet groups
erikdarlingdata Apr 6, 2026
4ab7cb0
Merge pull request #792 from erikdarlingdata/fix/archive-oom-and-fino…
erikdarlingdata Apr 6, 2026
0260844
Replace all muted/dim text colors with foreground colors for readability
erikdarlingdata Apr 6, 2026
9acf4f6
Add dynamic baselines and anomaly detection to Lite (#692, #693)
erikdarlingdata Apr 7, 2026
e2dfcdb
Port baseline engine and anomaly detection to Dashboard (Phases 5-8)
erikdarlingdata Apr 7, 2026
4c4602e
Merge pull request #793 from erikdarlingdata/feature/dashboard-baseli…
erikdarlingdata Apr 7, 2026
ff00af6
Port warning rule improvements from PerformanceStudio (#178)
erikdarlingdata Apr 7, 2026
51283a4
Merge pull request #795 from erikdarlingdata/fix/warning-improvements…
erikdarlingdata Apr 7, 2026
679eb9c
Refine Rule 3 (Serial Plan): TRIVIAL, 0ms, severity demotion
erikdarlingdata Apr 7, 2026
14e728a
Merge pull request #797 from erikdarlingdata/fix/rule3-serial-refinem…
erikdarlingdata Apr 7, 2026
26a13e0
Add before/after comparison mode for query grids in Lite (#687)
erikdarlingdata Apr 7, 2026
c1578cc
Fix collector health status for on-load collectors
erikdarlingdata Apr 7, 2026
7585494
Fix Rule 3 severity: CouldNotGenerateValidParallelPlan is actionable
erikdarlingdata Apr 7, 2026
2f9dc39
Merge pull request #799 from erikdarlingdata/fix/rule3-actionable-sev…
erikdarlingdata Apr 7, 2026
b8a760b
Port query grid comparison to Dashboard with global Compare dropdown
erikdarlingdata Apr 7, 2026
2c8af66
Expand Rule 3 to cover all 25 NonParallelPlanReason values
erikdarlingdata Apr 7, 2026
0545190
Merge pull request #800 from erikdarlingdata/fix/rule3-full-reasons
erikdarlingdata Apr 7, 2026
524b086
Merge pull request #798 from erikdarlingdata/feature/query-grid-compa…
erikdarlingdata Apr 7, 2026
f222150
Switch to release-signing and add SignPath sponsor attribution
erikdarlingdata Apr 7, 2026
e8e13e5
Fix CSV and clipboard exports writing StackPanel type name as column …
erikdarlingdata Apr 8, 2026
3e260f4
Merge pull request #801 from erikdarlingdata/feature/signpath-release…
erikdarlingdata Apr 8, 2026
6139aed
Merge pull request #806 from erikdarlingdata/fix/csv-header-stackpane…
erikdarlingdata Apr 8, 2026
a0bd819
Fix broken SignPath sponsor logo
erikdarlingdata Apr 8, 2026
eb9e498
Merge pull request #807 from erikdarlingdata/fix/signpath-logo
erikdarlingdata Apr 8, 2026
176ebfb
Release v2.6.0: version bumps and changelog
erikdarlingdata Apr 8, 2026
d300826
Merge pull request #808 from erikdarlingdata/release/v2.6.0
erikdarlingdata Apr 8, 2026
58b2db7
Fix SignPath logo SVG (was wrong image)
erikdarlingdata Apr 8, 2026
6f103c3
Merge pull request #809 from erikdarlingdata/fix/signpath-logo-correct
erikdarlingdata Apr 8, 2026
cb47ba2
Merge pull request #810 from erikdarlingdata/dev
erikdarlingdata Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ jobs:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '7969f8b6-d946-4a74-9bac-a55856d8b8e0'
project-slug: 'PerformanceMonitor'
signing-policy-slug: 'test-signing'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'Dashboard'
github-artifact-id: '${{ steps.upload-dashboard.outputs.artifact-id }}'
wait-for-completion: true
Expand All @@ -127,7 +127,7 @@ jobs:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '7969f8b6-d946-4a74-9bac-a55856d8b8e0'
project-slug: 'PerformanceMonitor'
signing-policy-slug: 'test-signing'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'Lite'
github-artifact-id: '${{ steps.upload-lite.outputs.artifact-id }}'
wait-for-completion: true
Expand All @@ -140,7 +140,7 @@ jobs:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '7969f8b6-d946-4a74-9bac-a55856d8b8e0'
project-slug: 'PerformanceMonitor'
signing-policy-slug: 'test-signing'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'Installers'
github-artifact-id: '${{ steps.upload-installer.outputs.artifact-id }}'
wait-for-completion: true
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ nul
Lite/config/servers.json
Lite/servers.json
Lite/collection_schedule.json

# Plans directory
plans/
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,51 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.6.0] - 2026-04-08

### Added

- **Correlated timeline lanes** on Lite Overview and Dashboard — synchronized CPU, memory, waits, and TempDB trend lanes for at-a-glance correlation ([#688])
- **Dynamic baselines and anomaly detection** in Lite and Dashboard — automatic baseline calculation with anomaly highlighting on key metrics ([#692], [#693])
- **Query grid comparison** — before/after comparison mode for query grids in Lite and Dashboard with global Compare dropdown ([#687])
- **Nonclustered index count badge** on modification operators in plan viewer ([#788])
- **Upgrade detection in Edit Server** dialog — see pending upgrades without adding a new server ([#772])
- **CLI installer interactive mode** prompts for trust-cert and encryption settings ([#784])
- **SignPath code signing** — release binaries are now digitally signed via the [SignPath FOSS](https://signpath.io) program

### Changed

- **PlanAnalyzer Rule 3 (Serial Plan)** comprehensively refined — severity demotion for TRIVIAL and 0ms plans, `CouldNotGenerateValidParallelPlan` treated as actionable, all 25 `NonParallelPlanReason` values now covered
- **PlanAnalyzer warning rules** ported from PerformanceStudio improvements
- **Text readability** — replaced all muted/dim text colors with full foreground colors for readability

### Fixed

- **Embedded resource upgrade discovery** broken — upgrades silently returned zero results for Dashboard installs ([#772])
- **Archive compaction OOM** on large parquet groups
- **CLI installer argument parsing** treating flags as positional args ([#786])
- **Lite long-running query alerts** firing on stale DuckDB snapshots
- **FinOps Enterprise feature detection** now queries all databases and filters to TDE only ([#780])
- **Second launch error** — now brings existing window to foreground instead ([#769])
- **Overview tab Memory Grant** showing 0 for all timestamps ([#776])
- **Lite FinOps Enterprise features** query error on servers without `database_id` column ([#777])
- **Collector health status** incorrect for on-load collectors
- **CSV and clipboard exports** writing `System.Windows.Controls.StackPanel` as column headers instead of actual header text ([#805])

[#687]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/687
[#688]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/688
[#692]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/692
[#693]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/693
[#769]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/769
[#772]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/772
[#776]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/776
[#777]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/777
[#780]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/780
[#784]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/784
[#786]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/786
[#788]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/788
[#805]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/805

## [2.5.0] - 2026-03-30

### Important
Expand Down
36 changes: 22 additions & 14 deletions Dashboard/AddServerDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Add SQL Server"
SizeToContent="Height" Width="500" MaxHeight="1050"
Height="750" Width="500"
WindowStartupLocation="CenterOwner"
ResizeMode="NoResize"
ResizeMode="CanResizeWithGrip"
Background="{DynamicResource BackgroundBrush}"
Foreground="{DynamicResource ForegroundBrush}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid Margin="20">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<!-- Header -->
Expand Down Expand Up @@ -217,14 +222,17 @@
Foreground="{DynamicResource ForegroundMutedBrush}"
TextWrapping="Wrap" Margin="0,8,0,0" Visibility="Collapsed"/>

<!-- Buttons -->
<StackPanel Grid.Row="6" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,15,0,0">
<Button x:Name="ViewReportButton" Content="View Report" Margin="0,0,8,0"
Click="ViewReport_Click" Visibility="Collapsed"/>
<Button x:Name="TestConnectionButton" Content="Test Connection" Margin="0,0,8,0" Click="TestConnection_Click"/>
<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}"/>
<Button Content="Cancel" Width="80" Height="30" Click="Cancel_Click" IsCancel="True"/>
</StackPanel>
</Grid>
</ScrollViewer>
</ScrollViewer>

<!-- Buttons pinned to bottom -->
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,15,0,0">
<Button x:Name="ViewReportButton" Content="View Report" Margin="0,0,8,0"
Click="ViewReport_Click" Visibility="Collapsed"/>
<Button x:Name="CheckForUpdatesButton" Content="Check for Updates" Margin="0,0,8,0" Click="CheckForUpdates_Click"/>
<Button x:Name="TestConnectionButton" Content="Test Connection" Margin="0,0,8,0" Click="TestConnection_Click"/>
<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}"/>
<Button Content="Cancel" Width="80" Height="30" Click="Cancel_Click" IsCancel="True"/>
</StackPanel>
</Grid>
</Window>
25 changes: 20 additions & 5 deletions Dashboard/AddServerDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,24 @@ happens after the connection test in DetectDatabaseStatusAsync() */
return (connected, errorMessage, mfaCancelled, serverVersion);
}

private async void CheckForUpdates_Click(object sender, RoutedEventArgs e)
{
if (!ValidateInputs()) return;

CheckForUpdatesButton.IsEnabled = false;
CheckForUpdatesButton.Content = "Checking...";

try
{
await DetectDatabaseStatusAsync();
}
finally
{
CheckForUpdatesButton.IsEnabled = true;
CheckForUpdatesButton.Content = "Check for Updates";
}
}

private async void TestConnection_Click(object sender, RoutedEventArgs e)
{
if (!ValidateInputs()) return;
Expand All @@ -331,11 +349,8 @@ private async void TestConnection_Click(object sender, RoutedEventArgs e)
MessageBoxImage.Information
);

/* After successful connection in Add mode, check database status */
if (!_isEditMode)
{
await DetectDatabaseStatusAsync();
}
/* After successful connection, check database status */
await DetectDatabaseStatusAsync();
}
else if (mfaCancelled)
{
Expand Down
4 changes: 3 additions & 1 deletion Dashboard/Analysis/AnalysisService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class AnalysisService
private readonly InferenceEngine _engine;
private readonly SqlServerDrillDownCollector _drillDown;
private readonly SqlServerAnomalyDetector _anomalyDetector;
private readonly SqlServerBaselineProvider _baselineProvider;

/// <summary>
/// Minimum hours of collected data required before analysis will run.
Expand Down Expand Up @@ -60,7 +61,8 @@ public AnalysisService(string connectionString, IPlanFetcher? planFetcher = null
_graph = new RelationshipGraph();
_engine = new InferenceEngine(_graph);
_drillDown = new SqlServerDrillDownCollector(connectionString, planFetcher);
_anomalyDetector = new SqlServerAnomalyDetector(connectionString);
_baselineProvider = new SqlServerBaselineProvider(connectionString);
_anomalyDetector = new SqlServerAnomalyDetector(connectionString, _baselineProvider);
}

/// <summary>
Expand Down
9 changes: 6 additions & 3 deletions Dashboard/Analysis/FactScorer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,12 @@ private static double ScoreBadActorFact(Fact fact)
/// </summary>
private static double ScoreAnomalyFact(Fact fact)
{
if ( fact.Key.StartsWith("ANOMALY_CPU_SPIKE" , StringComparison.OrdinalIgnoreCase)
|| fact.Key.StartsWith("ANOMALY_READ_LATENCY" , StringComparison.OrdinalIgnoreCase)
|| fact.Key.StartsWith("ANOMALY_WRITE_LATENCY", StringComparison.OrdinalIgnoreCase)
if ( fact.Key.StartsWith("ANOMALY_CPU_SPIKE" , StringComparison.OrdinalIgnoreCase)
|| fact.Key.StartsWith("ANOMALY_READ_LATENCY" , StringComparison.OrdinalIgnoreCase)
|| fact.Key.StartsWith("ANOMALY_WRITE_LATENCY" , StringComparison.OrdinalIgnoreCase)
|| fact.Key.StartsWith("ANOMALY_BATCH_REQUESTS", StringComparison.OrdinalIgnoreCase)
|| fact.Key.StartsWith("ANOMALY_SESSION_SPIKE" , StringComparison.OrdinalIgnoreCase)
|| fact.Key.StartsWith("ANOMALY_QUERY_DURATION", StringComparison.OrdinalIgnoreCase)
)
{
// Deviation-based scoring: 2σ = 0.5, 4σ = 1.0
Expand Down
Loading
Loading