diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/CompatibilitySuppressions.xml b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/CompatibilitySuppressions.xml
new file mode 100644
index 00000000000..32bf7744fbd
--- /dev/null
+++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/CompatibilitySuppressions.xml
@@ -0,0 +1,89 @@
+
+
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_UseDeltaNrPeriodsForCpuCalculation
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_UseDeltaNrPeriodsForCpuCalculation(System.Boolean)
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_UseDeltaNrPeriodsForCpuCalculation
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_UseDeltaNrPeriodsForCpuCalculation(System.Boolean)
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_UseDeltaNrPeriodsForCpuCalculation
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_UseDeltaNrPeriodsForCpuCalculation(System.Boolean)
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_CalculateCpuUsageWithoutHostDelta
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_CalculateCpuUsageWithoutHostDelta(System.Boolean)
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_CalculateCpuUsageWithoutHostDelta
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_CalculateCpuUsageWithoutHostDelta(System.Boolean)
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_CalculateCpuUsageWithoutHostDelta
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
+ CP0002
+ M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_CalculateCpuUsageWithoutHostDelta(System.Boolean)
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll
+ true
+
+
diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs
index af13b8100ba..5fb2f0a189e 100644
--- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs
+++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs
@@ -17,23 +17,16 @@ internal sealed class LinuxUtilizationProvider : ISnapshotProvider
{
private const double One = 1.0;
private const long Hundred = 100L;
- private const double CpuLimitThreshold110Percent = 1.1;
- // Meters to track CPU utilization threshold exceedances
- private readonly Counter? _cpuUtilizationLimit100PercentExceededCounter;
- private readonly Counter? _cpuUtilizationLimit110PercentExceededCounter;
-
- private readonly bool _useDeltaNrPeriods;
private readonly object _cpuLocker = new();
private readonly object _memoryLocker = new();
private readonly ILogger _logger;
private readonly ILinuxUtilizationParser _parser;
private readonly ulong _memoryLimit;
+ private readonly long _cpuPeriodsInterval;
private readonly TimeSpan _cpuRefreshInterval;
private readonly TimeSpan _memoryRefreshInterval;
private readonly TimeProvider _timeProvider;
- private readonly double _scaleRelativeToCpuLimit;
- private readonly double _scaleRelativeToCpuRequest;
private readonly double _scaleRelativeToCpuRequestForTrackerApi;
private readonly TimeSpan _retryInterval = TimeSpan.FromMinutes(5);
@@ -42,18 +35,11 @@ internal sealed class LinuxUtilizationProvider : ISnapshotProvider
private DateTimeOffset _refreshAfterCpu;
private DateTimeOffset _refreshAfterMemory;
-
- // Track the actual timestamp when we read CPU values
- private DateTimeOffset _lastCpuMeasurementTime;
-
private double _cpuPercentage = double.NaN;
private double _lastCpuCoresUsed = double.NaN;
private double _memoryPercentage;
private long _previousCgroupCpuTime;
private long _previousHostCpuTime;
- private long _cpuUtilizationLimit100PercentExceeded;
- private long _cpuUtilizationLimit110PercentExceeded;
- private long _cpuPeriodsInterval;
private long _previousCgroupCpuPeriodCounter;
public SystemResources Resources { get; }
@@ -66,7 +52,6 @@ public LinuxUtilizationProvider(IOptions options, ILi
DateTimeOffset now = _timeProvider.GetUtcNow();
_cpuRefreshInterval = options.Value.CpuConsumptionRefreshInterval;
_memoryRefreshInterval = options.Value.MemoryConsumptionRefreshInterval;
- _useDeltaNrPeriods = options.Value.UseDeltaNrPeriodsForCpuCalculation;
_refreshAfterCpu = now;
_refreshAfterMemory = now;
_memoryLimit = _parser.GetAvailableMemoryInBytes();
@@ -76,8 +61,8 @@ public LinuxUtilizationProvider(IOptions options, ILi
float hostCpus = _parser.GetHostCpuCount();
float cpuLimit = _parser.GetCgroupLimitedCpus();
float cpuRequest = _parser.GetCgroupRequestCpu();
- _scaleRelativeToCpuLimit = hostCpus / cpuLimit;
- _scaleRelativeToCpuRequest = hostCpus / cpuRequest;
+ float scaleRelativeToCpuLimit = hostCpus / cpuLimit;
+ float scaleRelativeToCpuRequest = hostCpus / cpuRequest;
_scaleRelativeToCpuRequestForTrackerApi = hostCpus; // the division by cpuRequest is performed later on in the ResourceUtilization class
#pragma warning disable CA2000 // Dispose objects before losing scope
@@ -87,21 +72,15 @@ public LinuxUtilizationProvider(IOptions options, ILi
var meter = meterFactory.Create(ResourceUtilizationInstruments.MeterName);
#pragma warning restore CA2000 // Dispose objects before losing scope
- if (options.Value.CalculateCpuUsageWithoutHostDelta)
+ if (options.Value.UseLinuxCalculationV2)
{
cpuLimit = _parser.GetCgroupLimitV2();
-
- // Try to get the CPU request from cgroup
cpuRequest = _parser.GetCgroupRequestCpuV2();
// Get Cpu periods interval from cgroup
_cpuPeriodsInterval = _parser.GetCgroupPeriodsIntervalInMicroSecondsV2();
(_previousCgroupCpuTime, _previousCgroupCpuPeriodCounter) = _parser.GetCgroupCpuUsageInNanosecondsAndCpuPeriodsV2();
- // Initialize the counters
- _cpuUtilizationLimit100PercentExceededCounter = meter.CreateCounter("cpu_utilization_limit_100_percent_exceeded");
- _cpuUtilizationLimit110PercentExceededCounter = meter.CreateCounter("cpu_utilization_limit_110_percent_exceeded");
-
_ = meter.CreateObservableGauge(
ResourceUtilizationInstruments.ContainerCpuLimitUtilization,
() => GetMeasurementWithRetry(() => CpuUtilizationLimit(cpuLimit)),
@@ -109,24 +88,24 @@ public LinuxUtilizationProvider(IOptions options, ILi
_ = meter.CreateObservableGauge(
name: ResourceUtilizationInstruments.ContainerCpuRequestUtilization,
- observeValues: () => GetMeasurementWithRetry(() => CpuUtilizationWithoutHostDelta() / cpuRequest),
+ observeValues: () => GetMeasurementWithRetry(() => CpuUtilizationRequest(cpuRequest)),
unit: "1");
}
else
{
_ = meter.CreateObservableGauge(
name: ResourceUtilizationInstruments.ContainerCpuLimitUtilization,
- observeValues: () => GetMeasurementWithRetry(() => CpuUtilization() * _scaleRelativeToCpuLimit),
+ observeValues: () => GetMeasurementWithRetry(() => CpuUtilization() * scaleRelativeToCpuLimit),
unit: "1");
_ = meter.CreateObservableGauge(
name: ResourceUtilizationInstruments.ContainerCpuRequestUtilization,
- observeValues: () => GetMeasurementWithRetry(() => CpuUtilization() * _scaleRelativeToCpuRequest),
+ observeValues: () => GetMeasurementWithRetry(() => CpuUtilization() * scaleRelativeToCpuRequest),
unit: "1");
_ = meter.CreateObservableGauge(
name: ResourceUtilizationInstruments.ProcessCpuUtilization,
- observeValues: () => GetMeasurementWithRetry(() => CpuUtilization() * _scaleRelativeToCpuRequest),
+ observeValues: () => GetMeasurementWithRetry(() => CpuUtilization() * scaleRelativeToCpuRequest),
unit: "1");
}
@@ -148,10 +127,9 @@ public LinuxUtilizationProvider(IOptions options, ILi
_logger.SystemResourcesInfo(cpuLimit, cpuRequest, _memoryLimit, _memoryLimit);
}
- public double CpuUtilizationWithoutHostDelta()
+ public double CpuUtilizationV2()
{
DateTimeOffset now = _timeProvider.GetUtcNow();
- double actualElapsedNanoseconds = (now - _lastCpuMeasurementTime).TotalNanoseconds;
lock (_cpuLocker)
{
if (now < _refreshAfterCpu)
@@ -160,79 +138,34 @@ public double CpuUtilizationWithoutHostDelta()
}
}
- var (cpuUsageTime, cpuPeriodCounter) = _parser.GetCgroupCpuUsageInNanosecondsAndCpuPeriodsV2();
+ (long cpuUsageTime, long cpuPeriodCounter) = _parser.GetCgroupCpuUsageInNanosecondsAndCpuPeriodsV2();
lock (_cpuLocker)
{
- if (now >= _refreshAfterCpu)
+ if (now < _refreshAfterCpu)
{
- long deltaCgroup = cpuUsageTime - _previousCgroupCpuTime;
- double coresUsed;
-
- if (_useDeltaNrPeriods)
- {
- long deltaPeriodCount = cpuPeriodCounter - _previousCgroupCpuPeriodCounter;
- long deltaCpuPeriodInNanoseconds = deltaPeriodCount * _cpuPeriodsInterval * 1000;
-
- if (deltaCgroup > 0 && deltaPeriodCount > 0)
- {
- coresUsed = deltaCgroup / (double)deltaCpuPeriodInNanoseconds;
-
- _logger.CpuUsageDataV2(cpuUsageTime, _previousCgroupCpuTime, deltaCpuPeriodInNanoseconds, coresUsed);
-
- _lastCpuCoresUsed = coresUsed;
- _refreshAfterCpu = now.Add(_cpuRefreshInterval);
- _previousCgroupCpuTime = cpuUsageTime;
- _previousCgroupCpuPeriodCounter = cpuPeriodCounter;
- }
- }
- else
- {
- if (deltaCgroup > 0)
- {
- coresUsed = deltaCgroup / actualElapsedNanoseconds;
-
- _logger.CpuUsageDataV2(cpuUsageTime, _previousCgroupCpuTime, actualElapsedNanoseconds, coresUsed);
-
- _lastCpuCoresUsed = coresUsed;
- _refreshAfterCpu = now.Add(_cpuRefreshInterval);
- _previousCgroupCpuTime = cpuUsageTime;
-
- // Update the timestamp for next calculation
- _lastCpuMeasurementTime = now;
- }
- }
+ return _lastCpuCoresUsed;
}
- }
- return _lastCpuCoresUsed;
- }
+ long deltaCgroup = cpuUsageTime - _previousCgroupCpuTime;
+ long deltaPeriodCount = cpuPeriodCounter - _previousCgroupCpuPeriodCounter;
- ///
- /// Calculates CPU utilization relative to the CPU limit.
- ///
- /// The CPU limit to use for the calculation.
- /// CPU usage as a ratio of the limit.
- public double CpuUtilizationLimit(float cpuLimit)
- {
- double utilization = CpuUtilizationWithoutHostDelta() / cpuLimit;
+ if (deltaCgroup <= 0 || deltaPeriodCount <= 0)
+ {
+ return _lastCpuCoresUsed;
+ }
- // Increment counter if utilization exceeds 1 (100%)
- if (utilization > 1.0)
- {
- _cpuUtilizationLimit100PercentExceededCounter?.Add(1);
- _cpuUtilizationLimit100PercentExceeded++;
- _logger.CounterMessage100(_cpuUtilizationLimit100PercentExceeded);
- }
+ long deltaCpuPeriodInNanoseconds = deltaPeriodCount * _cpuPeriodsInterval * 1000;
+ double coresUsed = deltaCgroup / (double)deltaCpuPeriodInNanoseconds;
- // Increment counter if utilization exceeds 110%
- if (utilization > CpuLimitThreshold110Percent)
- {
- _cpuUtilizationLimit110PercentExceededCounter?.Add(1);
- _cpuUtilizationLimit110PercentExceeded++;
- _logger.CounterMessage110(_cpuUtilizationLimit110PercentExceeded);
+ _logger.CpuUsageDataV2(cpuUsageTime, _previousCgroupCpuTime, deltaCpuPeriodInNanoseconds, coresUsed);
+
+ _lastCpuCoresUsed = coresUsed;
+ _refreshAfterCpu = now.Add(_cpuRefreshInterval);
+ _previousCgroupCpuTime = cpuUsageTime;
+ _previousCgroupCpuPeriodCounter = cpuPeriodCounter;
}
- return utilization;
+ return _lastCpuCoresUsed;
}
public double CpuUtilization()
@@ -252,23 +185,27 @@ public double CpuUtilization()
lock (_cpuLocker)
{
- if (now >= _refreshAfterCpu)
+ if (now < _refreshAfterCpu)
{
- long deltaHost = hostCpuTime - _previousHostCpuTime;
- long deltaCgroup = cgroupCpuTime - _previousCgroupCpuTime;
-
- if (deltaHost > 0 && deltaCgroup > 0)
- {
- double percentage = Math.Min(One, (double)deltaCgroup / deltaHost);
+ return _cpuPercentage;
+ }
- _logger.CpuUsageData(cgroupCpuTime, hostCpuTime, _previousCgroupCpuTime, _previousHostCpuTime, percentage);
+ long deltaHost = hostCpuTime - _previousHostCpuTime;
+ long deltaCgroup = cgroupCpuTime - _previousCgroupCpuTime;
- _cpuPercentage = percentage;
- _refreshAfterCpu = now.Add(_cpuRefreshInterval);
- _previousCgroupCpuTime = cgroupCpuTime;
- _previousHostCpuTime = hostCpuTime;
- }
+ if (deltaHost <= 0 || deltaCgroup <= 0)
+ {
+ return _cpuPercentage;
}
+
+ double percentage = Math.Min(One, (double)deltaCgroup / deltaHost);
+
+ _logger.CpuUsageData(cgroupCpuTime, hostCpuTime, _previousCgroupCpuTime, _previousHostCpuTime, percentage);
+
+ _cpuPercentage = percentage;
+ _refreshAfterCpu = now.Add(_cpuRefreshInterval);
+ _previousCgroupCpuTime = cgroupCpuTime;
+ _previousHostCpuTime = hostCpuTime;
}
return _cpuPercentage;
@@ -351,4 +288,9 @@ ex is System.IO.DirectoryNotFoundException ||
return Enumerable.Empty>();
}
}
+
+ // Math.Min() is used below to mitigate margin errors and various kinds of precisions losses
+ // due to the fact that the calculation itself is not an atomic operation:
+ private double CpuUtilizationRequest(double cpuRequest) => Math.Min(One, CpuUtilizationV2() / cpuRequest);
+ private double CpuUtilizationLimit(double cpuLimit) => Math.Min(One, CpuUtilizationV2() / cpuLimit);
}
diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/Log.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/Log.cs
index b78f64ddfe0..209a495e844 100644
--- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/Log.cs
+++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/Log.cs
@@ -50,19 +50,7 @@ public static partial void CpuUsageDataV2(
double actualElapsedNanoseconds,
double cpuCores);
- [LoggerMessage(5, LogLevel.Debug,
- "CPU utilization exceeded 100%: Counter = {counterValue}")]
- public static partial void CounterMessage100(
- this ILogger logger,
- long counterValue);
-
- [LoggerMessage(6, LogLevel.Debug,
- "CPU utilization exceeded 110%: Counter = {counterValue}")]
- public static partial void CounterMessage110(
- this ILogger logger,
- long counterValue);
-
- [LoggerMessage(7, LogLevel.Warning,
+ [LoggerMessage(5, LogLevel.Warning,
"Error while getting disk stats: Error={errorMessage}")]
public static partial void HandleDiskStatsException(
this ILogger logger,
diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.cs
index 420d6001f57..eb890da291e 100644
--- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.cs
+++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.cs
@@ -100,23 +100,18 @@ public partial class ResourceMonitoringOptions
public TimeSpan MemoryConsumptionRefreshInterval { get; set; } = DefaultRefreshInterval;
///
- /// Gets or sets a value indicating whether CPU metrics are calculated via cgroup CPU limits instead of Host CPU delta.
+ /// Gets or sets a value indicating whether CPU metrics for Linux are calculated using V2 method - via cgroup CPU limits instead of Host CPU delta.
///
///
/// The default value is .
///
+ ///
+ /// This applies to cgroups v2 only and not supported on cgroups v1.
+ /// This is a more accurate way to calculate CPU utilization on Linux systems, please enable if possible.
+ /// It will be the default in the future.
+ ///
[Experimental(diagnosticId: DiagnosticIds.Experiments.ResourceMonitoring, UrlFormat = DiagnosticIds.UrlFormat)]
- public bool CalculateCpuUsageWithoutHostDelta { get; set; }
-
- ///
- /// Gets or sets a value indicating whether to use the number of periods in cpu.stat for cgroup CPU usage.
- /// We use delta time for CPU usage calculation when this flag is not set.
- ///
- /// The default value is .
- ///
- ///
- [Experimental(diagnosticId: DiagnosticIds.Experiments.ResourceMonitoring, UrlFormat = DiagnosticIds.UrlFormat)]
- public bool UseDeltaNrPeriodsForCpuCalculation { get; set; }
+ public bool UseLinuxCalculationV2 { get; set; }
///
/// Gets or sets a value indicating whether disk I/O metrics should be enabled.
diff --git a/src/Shared/Instruments/ResourceUtilizationInstruments.cs b/src/Shared/Instruments/ResourceUtilizationInstruments.cs
index 3b3e4f80ea2..c0a230c84ea 100644
--- a/src/Shared/Instruments/ResourceUtilizationInstruments.cs
+++ b/src/Shared/Instruments/ResourceUtilizationInstruments.cs
@@ -89,22 +89,6 @@ internal static class ResourceUtilizationInstruments
/// The type of an instrument is .
///
public const string SystemNetworkConnections = "system.network.connections";
-
- ///
- /// The name of an instrument to count occurrences when CPU utilization exceeds 100% of the limit.
- ///
- ///
- /// The type of an instrument is .
- ///
- public const string CpuUtilizationLimit100PercentExceeded = "cpu.utilization.limit.100percent.exceeded";
-
- ///
- /// The name of an instrument to count occurrences when CPU utilization exceeds 110% of the limit.
- ///
- ///
- /// The type of an instrument is .
- ///
- public const string CpuUtilizationLimit110PercentExceeded = "cpu.utilization.limit.110percent.exceeded";
}
#pragma warning disable CS1574
diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs
index efaaea1a51a..b71ea1c47d2 100644
--- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs
+++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs
@@ -359,82 +359,6 @@ public Task ResourceUtilizationTracker_And_Metrics_Report_Same_Values_With_Cgrou
return Task.CompletedTask;
}
- [ConditionalFact]
- [CombinatorialData]
- [OSSkipCondition(OperatingSystems.Windows | OperatingSystems.MacOSX, SkipReason = "Linux specific tests")]
- public Task ResourceUtilizationTracker_And_Metrics_Report_Same_Values_With_Cgroupsv2_v2()
- {
- var cpuRefresh = TimeSpan.FromMinutes(13);
- var memoryRefresh = TimeSpan.FromMinutes(14);
- var fileSystem = new HardcodedValueFileSystem(new Dictionary
- {
- { new FileInfo("/proc/self/cgroup"), "0::/fakeslice"},
- { new FileInfo("/proc/stat"), "cpu 10 10 10 10 10 10 10 10 10 10"},
- { new FileInfo("/sys/fs/cgroup/fakeslice/cpu.stat"), "usage_usec 1020000\nnr_periods 50"},
- { new FileInfo("/sys/fs/cgroup/memory.max"), "1048576" },
- { new FileInfo("/proc/meminfo"), "MemTotal: 1024 kB"},
- { new FileInfo("/sys/fs/cgroup/cpuset.cpus.effective"), "0-19"},
- { new FileInfo("/sys/fs/cgroup/fakeslice/cpu.max"), "40000 10000"},
- { new FileInfo("/sys/fs/cgroup/fakeslice/cpu.weight"), "79"},
- });
-
- using var listener = new MeterListener();
- var clock = new FakeTimeProvider(DateTimeOffset.UtcNow);
- var cpuFromGauge = 0.0d;
- var cpuLimitFromGauge = 0.0d;
- var cpuRequestFromGauge = 0.0d;
- var memoryFromGauge = 0.0d;
- var memoryLimitFromGauge = 0.0d;
- using var e = new ManualResetEventSlim();
-
- object? meterScope = null;
- listener.InstrumentPublished = (Instrument instrument, MeterListener meterListener)
- => OnInstrumentPublished(instrument, meterListener, meterScope);
- listener.SetMeasurementEventCallback((m, f, _, _)
- => OnMeasurementReceived(m, f, ref cpuFromGauge, ref cpuLimitFromGauge, ref cpuRequestFromGauge, ref memoryFromGauge, ref memoryLimitFromGauge));
- listener.Start();
-
- using var host = FakeHost.CreateBuilder()
- .ConfigureServices(x =>
- x.AddLogging()
- .AddSingleton(clock)
- .AddSingleton(new FakeUserHz(100))
- .AddSingleton(fileSystem)
- .AddSingleton(new GenericPublisher(_ => e.Set()))
- .AddResourceMonitoring(x => x.ConfigureMonitor(options => options.CalculateCpuUsageWithoutHostDelta = true))
- .Replace(ServiceDescriptor.Singleton()))
- .Build();
-
- meterScope = host.Services.GetRequiredService();
- var tracker = host.Services.GetService();
- Assert.NotNull(tracker);
-
- _ = host.RunAsync();
-
- listener.RecordObservableInstruments();
-
- var utilization = tracker.GetUtilization(TimeSpan.FromSeconds(5));
-
- fileSystem.ReplaceFileContent(new FileInfo("/proc/stat"), "cpu 11 10 10 10 10 10 10 10 10 10");
- fileSystem.ReplaceFileContent(new FileInfo("/sys/fs/cgroup/fakeslice/cpu.stat"), "usage_usec 1120000\nnr_periods 56");
- fileSystem.ReplaceFileContent(new FileInfo("/sys/fs/cgroup/memory.current"), "524298");
- fileSystem.ReplaceFileContent(new FileInfo("/sys/fs/cgroup/memory.stat"), "inactive_file 10");
-
- clock.Advance(TimeSpan.FromSeconds(1));
- listener.RecordObservableInstruments();
-
- e.Wait();
-
- utilization = tracker.GetUtilization(TimeSpan.FromSeconds(1));
-
- var roundedCpuUsedPercentage = Math.Round(utilization.CpuUsedPercentage, 1);
-
- Assert.Equal(0, Math.Round(cpuLimitFromGauge * 100));
- Assert.Equal(0, Math.Round(cpuRequestFromGauge * 100));
-
- return Task.CompletedTask;
- }
-
[ConditionalFact]
[CombinatorialData]
[OSSkipCondition(OperatingSystems.Windows | OperatingSystems.MacOSX, SkipReason = "Linux specific tests")]
@@ -479,8 +403,7 @@ public Task ResourceUtilizationTracker_And_Metrics_Report_Same_Values_With_Cgrou
.AddSingleton(new GenericPublisher(_ => e.Set()))
.AddResourceMonitoring(x => x.ConfigureMonitor(options =>
{
- options.CalculateCpuUsageWithoutHostDelta = true;
- options.UseDeltaNrPeriodsForCpuCalculation = true;
+ options.UseLinuxCalculationV2 = true;
}))
.Replace(ServiceDescriptor.Singleton()))
.Build();
diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxUtilizationProviderTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxUtilizationProviderTests.cs
index 6ee3c40d44d..57b92bcfa85 100644
--- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxUtilizationProviderTests.cs
+++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxUtilizationProviderTests.cs
@@ -213,7 +213,7 @@ public void Provider_Registers_Instruments_CgroupV2_WithoutHostCpu()
{
var meterName = Guid.NewGuid().ToString();
var logger = new FakeLogger();
- var options = Options.Options.Create(new ResourceMonitoringOptions { CalculateCpuUsageWithoutHostDelta = true });
+ var options = Options.Options.Create(new ResourceMonitoringOptions { UseLinuxCalculationV2 = true });
using var meter = new Meter(nameof(Provider_Registers_Instruments_CgroupV2_WithoutHostCpu));
var meterFactoryMock = new Mock();
meterFactoryMock.Setup(x => x.Create(It.IsAny()))
diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceMonitoringOptionsTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceMonitoringOptionsTests.cs
index 1a40889fd72..ca3126e8b97 100644
--- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceMonitoringOptionsTests.cs
+++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceMonitoringOptionsTests.cs
@@ -19,7 +19,7 @@ public void Basic()
};
Assert.NotNull(options);
- Assert.False(options.CalculateCpuUsageWithoutHostDelta);
+ Assert.False(options.UseLinuxCalculationV2);
}
[Fact]
@@ -27,9 +27,9 @@ public void CalculateCpuUsageWithoutHostDelta_WhenSet_ReturnsExpectedValue()
{
var options = new ResourceMonitoringOptions
{
- CalculateCpuUsageWithoutHostDelta = true
+ UseLinuxCalculationV2 = true
};
- Assert.True(options.CalculateCpuUsageWithoutHostDelta);
+ Assert.True(options.UseLinuxCalculationV2);
}
}