diff --git a/FabricObserver.Extensibility/ObserverBase.cs b/FabricObserver.Extensibility/ObserverBase.cs index ebdb529c..d6e5fb6e 100644 --- a/FabricObserver.Extensibility/ObserverBase.cs +++ b/FabricObserver.Extensibility/ObserverBase.cs @@ -320,12 +320,12 @@ namespace FabricObserver.Observers public TimeSpan CpuMonitorDuration { - get => ConfigurationSettings?.CpuMonitorDuration ?? TimeSpan.FromSeconds(4); + get => ConfigurationSettings?.CpuMonitorDuration ?? TimeSpan.FromSeconds(3); set { if (ConfigurationSettings != null) { - ConfigurationSettings.CpuMonitorDuration = value >= TimeSpan.FromSeconds(1) ? value : TimeSpan.FromSeconds(1); + ConfigurationSettings.CpuMonitorDuration = value; } } } diff --git a/FabricObserver/Observers/AppObserver.cs b/FabricObserver/Observers/AppObserver.cs index 78c349b4..35fe0d72 100644 --- a/FabricObserver/Observers/AppObserver.cs +++ b/FabricObserver/Observers/AppObserver.cs @@ -3130,44 +3130,8 @@ namespace FabricObserver.Observers // CPU \\ - ICpuUsage cpuUsage; - - if (IsWindows) - { - cpuUsage = new CpuUsageWin32(); - } - else - { - cpuUsage = new CpuUsageProcess(); - } - - Stopwatch timer = Stopwatch.StartNew(); SafeProcessHandle procHandle = null; - - // CpuMonitorDuration can't be set to greater than 10s. - TimeSpan monitorDuration = CpuMonitorDuration <= TimeSpan.FromSeconds(10) ? CpuMonitorDuration : TimeSpan.FromSeconds(10); - - // CpuMonitorLoopSleepDuration can't be set to less than 500 milliseconds. - TimeSpan monitorLoopSleepTime = CpuMonitorLoopSleepDuration; - - // At least one value is needed to compute CPU Time % (in fact, more than one is best on Windows). If the user misconfigures sleep time to be greater than monitor duration, - // then we'll just set it to 1000 ms. - if (monitorLoopSleepTime > monitorDuration) - { - monitorLoopSleepTime = TimeSpan.FromMilliseconds(1000); - } - - // Limit high potential CPU usage by FO by limiting the duration of the CPU monitoring loop. - if (EnableConcurrentMonitoring) - { - if (monitorDuration >= TimeSpan.FromSeconds(5)) - { - monitorDuration = TimeSpan.FromSeconds(5); - - // Always force 1s sleep time for concurrent monitoring when duration is >= 5s. - monitorLoopSleepTime = TimeSpan.FromSeconds(1000); - } - } + ICpuUsage cpuUsage; if (IsWindows) { @@ -3177,14 +3141,47 @@ namespace FabricObserver.Observers { return; } + + cpuUsage = new CpuUsageWin32(); } + else + { + cpuUsage = new CpuUsageProcess(); + } + + // CpuMonitorDuration can't be set to greater than 10s. + TimeSpan cpuMonitorDuration = CpuMonitorDuration <= TimeSpan.FromSeconds(10) ? CpuMonitorDuration : TimeSpan.FromSeconds(10); + + // CpuMonitorLoopSleepDuration can't be set to less than 500 milliseconds. + TimeSpan cpuMonitorLoopSleepTime = CpuMonitorLoopSleepDuration; + + // At least one value is needed to compute CPU Time % (in fact, more than one is best on Windows). If the user misconfigures sleep time to be greater than monitor duration, + // then we'll just set it to 1000 ms. + if (cpuMonitorLoopSleepTime > cpuMonitorDuration) + { + cpuMonitorLoopSleepTime = TimeSpan.FromMilliseconds(1000); + } + + // Limit potential for high CPU usage by throttling max duration when monitoring CPU usage with multiple threads. + if (EnableConcurrentMonitoring) + { + if (cpuMonitorDuration >= TimeSpan.FromSeconds(5)) + { + cpuMonitorDuration = TimeSpan.FromSeconds(5); + + // Always force 1s sleep time for concurrent monitoring when duration is >= 5s. + cpuMonitorLoopSleepTime = TimeSpan.FromSeconds(1000); + } + } + + Stopwatch timer = Stopwatch.StartNew(); try { #if DEBUG ObserverLogger.LogInfo($"ComputeResourceUsage: Entering CPU monitor while loop. MonitorDuration = {CpuMonitorDuration}. CpuMonitorLoopSleepDuration = {CpuMonitorLoopSleepDuration}."); #endif - while (timer.Elapsed <= monitorDuration) + while (timer.Elapsed <= cpuMonitorDuration) { if (token.IsCancellationRequested) { @@ -3250,7 +3247,7 @@ namespace FabricObserver.Observers } } - Thread.Sleep(monitorLoopSleepTime); + Thread.Sleep(cpuMonitorLoopSleepTime); } #if DEBUG ObserverLogger.LogInfo($"ComputeResourceUsage: Exiting CPU monitoring while loop. Ran for {timer.Elapsed}."); diff --git a/FabricObserver/Observers/FabricSystemObserver.cs b/FabricObserver/Observers/FabricSystemObserver.cs index 2f6b7d48..cdb4ec44 100644 --- a/FabricObserver/Observers/FabricSystemObserver.cs +++ b/FabricObserver/Observers/FabricSystemObserver.cs @@ -1043,6 +1043,7 @@ namespace FabricObserver.Observers if (IsWindows) { cpuUsage = new CpuUsageWin32(); + procHandle = NativeMethods.GetSafeProcessHandle(procId); } else { @@ -1050,23 +1051,18 @@ namespace FabricObserver.Observers } Stopwatch timer = Stopwatch.StartNew(); - TimeSpan monitorDuration = CpuMonitorDuration; - TimeSpan monitorLoopSleepTime = CpuMonitorLoopSleepDuration; + TimeSpan cpuMonitorDuration = CpuMonitorDuration; + TimeSpan cpuMonitorLoopSleepTime = CpuMonitorLoopSleepDuration; // At least one value is needed to compute CPU Time % (in fact, more than one is best on Windows). If the user misconfigures sleep time to be greater than monitor duration, // then we'll just set it to 1000 ms. - if (monitorLoopSleepTime > monitorDuration) + if (cpuMonitorLoopSleepTime > cpuMonitorDuration) { // CpuMonitorDuration can't be set to less than 1 second. - monitorLoopSleepTime = TimeSpan.FromMilliseconds(1000); + cpuMonitorLoopSleepTime = TimeSpan.FromMilliseconds(1000); } - if (IsWindows) - { - procHandle = NativeMethods.GetSafeProcessHandle(procId); - } - - while (timer.Elapsed <= monitorDuration) + while (timer.Elapsed <= cpuMonitorDuration) { token.ThrowIfCancellationRequested(); @@ -1083,7 +1079,7 @@ namespace FabricObserver.Observers } } - await Task.Delay(monitorLoopSleepTime, token); + await Task.Delay(cpuMonitorLoopSleepTime, token); } catch (Exception e) when (e is not (OperationCanceledException or TaskCanceledException)) {