@@ -24,16 +24,18 @@ public partial class LocalDataService
2424 using var connection = await OpenConnectionAsync ( ) ;
2525
2626 double ? cpuPercent = null ;
27+ double ? otherProcessCpuPercent = null ;
2728 double ? memoryMb = null ;
2829 int blockingCount = 0 ;
2930 int deadlockCount = 0 ;
3031 DateTime ? lastCollection = null ;
3132
32- /* Latest CPU */
33+ /* Latest CPU — read both SQL Server CPU and other-process CPU so the UI can surface
34+ total non-idle CPU alongside the SQL-only number. */
3335 using ( var cmd = connection . CreateCommand ( ) )
3436 {
3537 cmd . CommandText = @"
36- SELECT sqlserver_cpu_utilization, sample_time
38+ SELECT sqlserver_cpu_utilization, other_process_cpu_utilization, sample_time
3739FROM v_cpu_utilization_stats
3840WHERE server_id = $1
3941ORDER BY sample_time DESC
@@ -43,7 +45,8 @@ ORDER BY sample_time DESC
4345 if ( await reader . ReadAsync ( ) )
4446 {
4547 cpuPercent = reader . IsDBNull ( 0 ) ? null : ToDouble ( reader . GetValue ( 0 ) ) ;
46- lastCollection = reader . IsDBNull ( 1 ) ? null : reader . GetDateTime ( 1 ) ;
48+ otherProcessCpuPercent = reader . IsDBNull ( 1 ) ? null : ToDouble ( reader . GetValue ( 1 ) ) ;
49+ lastCollection = reader . IsDBNull ( 2 ) ? null : reader . GetDateTime ( 2 ) ;
4750 }
4851 }
4952
@@ -112,6 +115,7 @@ FROM v_collection_log
112115 DisplayName = displayName ,
113116 ServerId = serverId ,
114117 CpuPercent = cpuPercent ,
118+ OtherProcessCpuPercent = otherProcessCpuPercent ,
115119 MemoryMb = memoryMb ,
116120 BlockingCount = blockingCount ,
117121 DeadlockCount = deadlockCount ,
@@ -128,13 +132,34 @@ public class ServerSummaryItem
128132 public bool ? IsOnline { get ; set ; }
129133 /// <summary>True when the server is reachable but one or more collectors have consecutive errors.</summary>
130134 public bool HasCollectorErrors { get ; set ; }
135+ /// <summary>SQL Server scheduler ProcessUtilization from sys.dm_os_ring_buffers. NULL on Azure SQL DB.</summary>
131136 public double ? CpuPercent { get ; set ; }
137+ /// <summary>Non-SQL-Server CPU on the host (computed as 100 - SystemIdle - ProcessUtilization). NULL on Azure SQL DB.</summary>
138+ public double ? OtherProcessCpuPercent { get ; set ; }
139+ /// <summary>Total non-idle CPU on the host = sql_server + other_process. Tracks closer to OS user+system counters.</summary>
140+ public double ? TotalCpuPercent =>
141+ CpuPercent . HasValue ? CpuPercent . Value + ( OtherProcessCpuPercent ?? 0 ) : null ;
142+ /// <summary>The CPU value the alert evaluator and headline display use. Driven by App.AlertCpuMode.</summary>
143+ public double ? CpuPercentForAlert =>
144+ App . AlertCpuMode == CpuAlertMode . Total ? ( TotalCpuPercent ?? CpuPercent ) : CpuPercent ;
132145 public double ? MemoryMb { get ; set ; }
133146 public int BlockingCount { get ; set ; }
134147 public int DeadlockCount { get ; set ; }
135148 public DateTime ? LastCollectionTime { get ; set ; }
136149
137- public string CpuDisplay => CpuPercent . HasValue ? $ "{ CpuPercent : F0} %" : "--" ;
150+ /// <summary>
151+ /// Headline CPU display. Shows total non-idle CPU prominently with the SQL-only number alongside,
152+ /// e.g. "64% (SQL 60%)". Falls back to a single number when only one value is available.
153+ /// </summary>
154+ public string CpuDisplay
155+ {
156+ get
157+ {
158+ if ( ! CpuPercent . HasValue ) return "--" ;
159+ if ( ! OtherProcessCpuPercent . HasValue ) return $ "{ CpuPercent : F0} %";
160+ return $ "{ TotalCpuPercent : F0} % (SQL { CpuPercent : F0} %)";
161+ }
162+ }
138163 public string MemoryDisplay => MemoryMb . HasValue ? $ "{ MemoryMb / 1024.0 : F1} GB" : "--" ;
139164 public string BlockingDisplay => BlockingCount > 0 ? BlockingCount . ToString ( ) : "0" ;
140165 public string DeadlockDisplay => DeadlockCount > 0 ? DeadlockCount . ToString ( ) : "0" ;
@@ -158,14 +183,21 @@ public class ServerSummaryItem
158183 public bool IsOffline => IsOnline == false ;
159184
160185 /* Color coding */
161- public SolidColorBrush CpuBrush => MakeBrush ( CpuPercent >= 80 ? "#E57373" : CpuPercent >= 50 ? "#FFB74D" : "#81C784" ) ;
186+ public SolidColorBrush CpuBrush
187+ {
188+ get
189+ {
190+ var v = CpuPercentForAlert ;
191+ return MakeBrush ( v >= 80 ? "#E57373" : v >= 50 ? "#FFB74D" : "#81C784" ) ;
192+ }
193+ }
162194 public SolidColorBrush BlockingBrush => MakeBrush ( BlockingCount > 0 ? "#FFB74D" : "#81C784" ) ;
163195 public SolidColorBrush DeadlockBrush => MakeBrush ( DeadlockCount > 0 ? "#E57373" : "#81C784" ) ;
164196 public SolidColorBrush CardBorderBrush => MakeBrush (
165197 IsOnline == false ? "#E57373" :
166198 DeadlockCount > 0 ? "#E57373" :
167199 BlockingCount > 0 ? "#FFB74D" :
168- CpuPercent >= 80 ? "#FFB74D" :
200+ CpuPercentForAlert >= 80 ? "#FFB74D" :
169201 HasCollectorErrors ? "#FFD54F" : // amber border when collectors are failing
170202 "#2a2d35" ) ;
171203
0 commit comments