diff --git a/Dashboard/Controls/CurrentConfigContent.xaml b/Dashboard/Controls/CurrentConfigContent.xaml
new file mode 100644
index 00000000..9108c2f6
--- /dev/null
+++ b/Dashboard/Controls/CurrentConfigContent.xaml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Dashboard/Controls/CurrentConfigContent.xaml.cs b/Dashboard/Controls/CurrentConfigContent.xaml.cs
new file mode 100644
index 00000000..4700a14d
--- /dev/null
+++ b/Dashboard/Controls/CurrentConfigContent.xaml.cs
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2026 Erik Darling, Darling Data LLC
+ *
+ * This file is part of the SQL Server Performance Monitor.
+ *
+ * Licensed under the MIT License. See LICENSE file in the project root for full license information.
+ */
+
+using System;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using PerformanceMonitorDashboard.Helpers;
+using PerformanceMonitorDashboard.Services;
+
+namespace PerformanceMonitorDashboard.Controls
+{
+ public partial class CurrentConfigContent : UserControl
+ {
+ private DatabaseService? _databaseService;
+
+ public CurrentConfigContent()
+ {
+ InitializeComponent();
+ }
+
+ public void Initialize(DatabaseService databaseService)
+ {
+ _databaseService = databaseService;
+ }
+
+ public async Task RefreshAllDataAsync()
+ {
+ if (_databaseService == null) return;
+
+ await Task.WhenAll(
+ RefreshServerConfigAsync(),
+ RefreshDatabaseConfigAsync(),
+ RefreshTraceFlagsAsync()
+ );
+ }
+
+ private void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ TabHelpers.AutoSizeColumnMinWidths(ServerConfigDataGrid);
+ TabHelpers.AutoSizeColumnMinWidths(DatabaseConfigDataGrid);
+ TabHelpers.AutoSizeColumnMinWidths(TraceFlagsDataGrid);
+ TabHelpers.FreezeColumns(ServerConfigDataGrid, 1);
+ TabHelpers.FreezeColumns(DatabaseConfigDataGrid, 1);
+ }
+
+ #region Server Configuration
+
+ private async Task RefreshServerConfigAsync()
+ {
+ if (_databaseService == null) return;
+
+ try
+ {
+ var data = await _databaseService.GetCurrentServerConfigAsync();
+ ServerConfigDataGrid.ItemsSource = data;
+ ServerConfigNoDataMessage.Visibility = data.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
+ }
+ catch (Exception ex)
+ {
+ Logger.Error($"Error loading server configuration: {ex.Message}");
+ }
+ }
+
+ private void ServerConfigFilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ DataGridFilterService.ApplyFilter(ServerConfigDataGrid, sender as TextBox);
+ }
+
+ #endregion
+
+ #region Database Configuration
+
+ private async Task RefreshDatabaseConfigAsync()
+ {
+ if (_databaseService == null) return;
+
+ try
+ {
+ var data = await _databaseService.GetCurrentDatabaseConfigAsync();
+ DatabaseConfigDataGrid.ItemsSource = data;
+ DatabaseConfigNoDataMessage.Visibility = data.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
+ }
+ catch (Exception ex)
+ {
+ Logger.Error($"Error loading database configuration: {ex.Message}");
+ }
+ }
+
+ private void DatabaseConfigFilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ DataGridFilterService.ApplyFilter(DatabaseConfigDataGrid, sender as TextBox);
+ }
+
+ #endregion
+
+ #region Trace Flags
+
+ private async Task RefreshTraceFlagsAsync()
+ {
+ if (_databaseService == null) return;
+
+ try
+ {
+ var data = await _databaseService.GetCurrentTraceFlagsAsync();
+ TraceFlagsDataGrid.ItemsSource = data;
+ TraceFlagsNoDataMessage.Visibility = data.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
+ }
+ catch (Exception ex)
+ {
+ Logger.Error($"Error loading trace flags: {ex.Message}");
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Dashboard/Models/CurrentServerConfigItem.cs b/Dashboard/Models/CurrentServerConfigItem.cs
new file mode 100644
index 00000000..50ccc375
--- /dev/null
+++ b/Dashboard/Models/CurrentServerConfigItem.cs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2026 Erik Darling, Darling Data LLC
+ *
+ * This file is part of the SQL Server Performance Monitor.
+ *
+ * Licensed under the MIT License. See LICENSE file in the project root for full license information.
+ */
+
+using System;
+
+namespace PerformanceMonitorDashboard.Models
+{
+ public class CurrentServerConfigItem
+ {
+ public string ConfigurationName { get; set; } = string.Empty;
+ public string ValueConfigured { get; set; } = string.Empty;
+ public string ValueInUse { get; set; } = string.Empty;
+ public string ValueMinimum { get; set; } = string.Empty;
+ public string ValueMaximum { get; set; } = string.Empty;
+ public bool IsDynamic { get; set; }
+ public bool IsAdvanced { get; set; }
+ public string Description { get; set; } = string.Empty;
+ public DateTime LastChanged { get; set; }
+ }
+
+ public class CurrentDatabaseConfigItem
+ {
+ public string DatabaseName { get; set; } = string.Empty;
+ public string SettingType { get; set; } = string.Empty;
+ public string SettingName { get; set; } = string.Empty;
+ public string SettingValue { get; set; } = string.Empty;
+ public DateTime LastChanged { get; set; }
+ }
+
+ public class CurrentTraceFlagItem
+ {
+ public int TraceFlag { get; set; }
+ public bool Status { get; set; }
+ public bool IsGlobal { get; set; }
+ public bool IsSession { get; set; }
+ public DateTime LastChanged { get; set; }
+ }
+}
diff --git a/Dashboard/ServerTab.xaml b/Dashboard/ServerTab.xaml
index fa7f83b4..526137c9 100644
--- a/Dashboard/ServerTab.xaml
+++ b/Dashboard/ServerTab.xaml
@@ -229,6 +229,11 @@
+
+
+
+
+
diff --git a/Dashboard/ServerTab.xaml.cs b/Dashboard/ServerTab.xaml.cs
index 58acbcf6..9ee1de2d 100644
--- a/Dashboard/ServerTab.xaml.cs
+++ b/Dashboard/ServerTab.xaml.cs
@@ -115,6 +115,7 @@ public ServerTab(ServerConnection serverConnection, int utcOffsetMinutes = 0)
DailySummaryTab.Initialize(_databaseService);
CriticalIssuesTab.Initialize(_databaseService);
DefaultTraceTab.Initialize(_databaseService);
+ CurrentConfigTab.Initialize(_databaseService);
MemoryTab.Initialize(_databaseService);
PerformanceTab.Initialize(_databaseService, s => StatusText.Text = s);
SystemEventsContent.Initialize(_databaseService);
@@ -1169,6 +1170,7 @@ private async Task ApplyAndRefreshCurrentTabAsync()
CollectionHealth_Refresh_Click(null, new RoutedEventArgs());
await CriticalIssuesTab.RefreshDataAsync();
await DefaultTraceTab.RefreshAllDataAsync();
+ await CurrentConfigTab.RefreshAllDataAsync();
await RefreshResourceOverviewAsync();
break;
@@ -1278,13 +1280,14 @@ private async Task LoadDataAsync()
var dailySummaryTask = DailySummaryTab.RefreshDataAsync();
var criticalIssuesTask = CriticalIssuesTab.RefreshDataAsync();
var defaultTraceTask = DefaultTraceTab.RefreshAllDataAsync();
+ var currentConfigTask = CurrentConfigTab.RefreshAllDataAsync();
var systemEventsTask = SystemEventsContent.RefreshAllDataAsync();
// Wait for everything to complete before _isRefreshing resets
await Task.WhenAll(
healthTask, blockingEventsTask, deadlocksTask, blockingStatsTask, lockWaitStatsTask,
performanceTask, memoryTask, resourceOverviewTask, runningJobsTask,
- resourceMetricsTask, dailySummaryTask, criticalIssuesTask, defaultTraceTask, systemEventsTask);
+ resourceMetricsTask, dailySummaryTask, criticalIssuesTask, defaultTraceTask, currentConfigTask, systemEventsTask);
// Populate grids with fetched data
var healthData = await healthTask;
diff --git a/Dashboard/Services/DatabaseService.SystemEvents.cs b/Dashboard/Services/DatabaseService.SystemEvents.cs
index 1e6b21ab..114dfe1b 100644
--- a/Dashboard/Services/DatabaseService.SystemEvents.cs
+++ b/Dashboard/Services/DatabaseService.SystemEvents.cs
@@ -1175,5 +1175,179 @@ FROM collect.HealthParser_MemoryNodeOOM AS hpmn
return items;
}
+
+ public async Task> GetCurrentServerConfigAsync()
+ {
+ var items = new List();
+
+ await using var tc = await OpenThrottledConnectionAsync();
+ var connection = tc.Connection;
+
+ string query = @"
+ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+
+ WITH
+ latest AS
+ (
+ SELECT
+ h.configuration_id,
+ h.configuration_name,
+ h.value_configured,
+ h.value_in_use,
+ h.value_minimum,
+ h.value_maximum,
+ h.is_dynamic,
+ h.is_advanced,
+ h.description,
+ h.collection_time,
+ rn = ROW_NUMBER() OVER (PARTITION BY h.configuration_id ORDER BY h.collection_time DESC)
+ FROM config.server_configuration_history AS h
+ )
+ SELECT
+ l.configuration_name,
+ value_configured = CONVERT(nvarchar(100), l.value_configured),
+ value_in_use = CONVERT(nvarchar(100), l.value_in_use),
+ value_minimum = CONVERT(nvarchar(100), l.value_minimum),
+ value_maximum = CONVERT(nvarchar(100), l.value_maximum),
+ l.is_dynamic,
+ l.is_advanced,
+ l.description,
+ last_changed = l.collection_time
+ FROM latest AS l
+ WHERE l.rn = 1
+ ORDER BY
+ l.configuration_name;";
+
+ using var command = new SqlCommand(query, connection);
+ command.CommandTimeout = 30;
+
+ using var reader = await command.ExecuteReaderAsync();
+ while (await reader.ReadAsync())
+ {
+ items.Add(new CurrentServerConfigItem
+ {
+ ConfigurationName = reader.GetString(0),
+ ValueConfigured = reader.IsDBNull(1) ? string.Empty : reader.GetString(1),
+ ValueInUse = reader.IsDBNull(2) ? string.Empty : reader.GetString(2),
+ ValueMinimum = reader.IsDBNull(3) ? string.Empty : reader.GetString(3),
+ ValueMaximum = reader.IsDBNull(4) ? string.Empty : reader.GetString(4),
+ IsDynamic = reader.GetBoolean(5),
+ IsAdvanced = reader.GetBoolean(6),
+ Description = reader.IsDBNull(7) ? string.Empty : reader.GetString(7),
+ LastChanged = reader.GetDateTime(8)
+ });
+ }
+
+ return items;
+ }
+
+ public async Task> GetCurrentDatabaseConfigAsync()
+ {
+ var items = new List();
+
+ await using var tc = await OpenThrottledConnectionAsync();
+ var connection = tc.Connection;
+
+ string query = @"
+ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+
+ WITH
+ latest AS
+ (
+ SELECT
+ h.database_name,
+ h.setting_type,
+ h.setting_name,
+ h.setting_value,
+ h.collection_time,
+ rn = ROW_NUMBER() OVER (
+ PARTITION BY h.database_name, h.setting_type, h.setting_name
+ ORDER BY h.collection_time DESC
+ )
+ FROM config.database_configuration_history AS h
+ )
+ SELECT
+ l.database_name,
+ l.setting_type,
+ l.setting_name,
+ setting_value = CONVERT(nvarchar(500), l.setting_value),
+ last_changed = l.collection_time
+ FROM latest AS l
+ WHERE l.rn = 1
+ ORDER BY
+ l.database_name,
+ l.setting_type,
+ l.setting_name;";
+
+ using var command = new SqlCommand(query, connection);
+ command.CommandTimeout = 30;
+
+ using var reader = await command.ExecuteReaderAsync();
+ while (await reader.ReadAsync())
+ {
+ items.Add(new CurrentDatabaseConfigItem
+ {
+ DatabaseName = reader.GetString(0),
+ SettingType = reader.GetString(1),
+ SettingName = reader.GetString(2),
+ SettingValue = reader.IsDBNull(3) ? string.Empty : reader.GetString(3),
+ LastChanged = reader.GetDateTime(4)
+ });
+ }
+
+ return items;
+ }
+
+ public async Task> GetCurrentTraceFlagsAsync()
+ {
+ var items = new List();
+
+ await using var tc = await OpenThrottledConnectionAsync();
+ var connection = tc.Connection;
+
+ string query = @"
+ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+
+ WITH
+ latest AS
+ (
+ SELECT
+ h.trace_flag,
+ h.status,
+ h.is_global,
+ h.is_session,
+ h.collection_time,
+ rn = ROW_NUMBER() OVER (PARTITION BY h.trace_flag ORDER BY h.collection_time DESC)
+ FROM config.trace_flags_history AS h
+ )
+ SELECT
+ l.trace_flag,
+ l.status,
+ l.is_global,
+ l.is_session,
+ last_changed = l.collection_time
+ FROM latest AS l
+ WHERE l.rn = 1
+ ORDER BY
+ l.trace_flag;";
+
+ using var command = new SqlCommand(query, connection);
+ command.CommandTimeout = 30;
+
+ using var reader = await command.ExecuteReaderAsync();
+ while (await reader.ReadAsync())
+ {
+ items.Add(new CurrentTraceFlagItem
+ {
+ TraceFlag = reader.GetInt32(0),
+ Status = reader.GetBoolean(1),
+ IsGlobal = reader.GetBoolean(2),
+ IsSession = reader.GetBoolean(3),
+ LastChanged = reader.GetDateTime(4)
+ });
+ }
+
+ return items;
+ }
}
}