Skip to content

Commit 4e16fae

Browse files
author
evgenyfedorov2
committed
Fix tests
Update CompatibilitySuppressions Remove unnecessary logging and metrics Rename CalculateCpuUsageWithoutHostDelta to UseLinuxCpuUsageV2 Remove UseDeltaNrPeriosForCpuCalculaton
1 parent 8148872 commit 4e16fae

File tree

8 files changed

+145
-229
lines changed

8 files changed

+145
-229
lines changed

src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/CompatibilitySuppressions.xml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,90 @@
4343
<Right>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
4444
<IsBaselineSuppression>true</IsBaselineSuppression>
4545
</Suppression>
46+
47+
<Suppression>
48+
<DiagnosticId>CP0002</DiagnosticId>
49+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_UseDeltaNrPeriodsForCpuCalculation</Target>
50+
<Left>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
51+
<Right>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
52+
<IsBaselineSuppression>true</IsBaselineSuppression>
53+
</Suppression>
54+
<Suppression>
55+
<DiagnosticId>CP0002</DiagnosticId>
56+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_UseDeltaNrPeriodsForCpuCalculation(System.Boolean)</Target>
57+
<Left>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
58+
<Right>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
59+
<IsBaselineSuppression>true</IsBaselineSuppression>
60+
</Suppression>
61+
<Suppression>
62+
<DiagnosticId>CP0002</DiagnosticId>
63+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_UseDeltaNrPeriodsForCpuCalculation</Target>
64+
<Left>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
65+
<Right>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
66+
<IsBaselineSuppression>true</IsBaselineSuppression>
67+
</Suppression>
68+
<Suppression>
69+
<DiagnosticId>CP0002</DiagnosticId>
70+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_UseDeltaNrPeriodsForCpuCalculation(System.Boolean)</Target>
71+
<Left>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
72+
<Right>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
73+
<IsBaselineSuppression>true</IsBaselineSuppression>
74+
</Suppression>
75+
<Suppression>
76+
<DiagnosticId>CP0002</DiagnosticId>
77+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_UseDeltaNrPeriodsForCpuCalculation</Target>
78+
<Left>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
79+
<Right>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
80+
<IsBaselineSuppression>true</IsBaselineSuppression>
81+
</Suppression>
82+
<Suppression>
83+
<DiagnosticId>CP0002</DiagnosticId>
84+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_UseDeltaNrPeriodsForCpuCalculation(System.Boolean)</Target>
85+
<Left>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
86+
<Right>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
87+
<IsBaselineSuppression>true</IsBaselineSuppression>
88+
</Suppression>
89+
90+
<Suppression>
91+
<DiagnosticId>CP0002</DiagnosticId>
92+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_CalculateCpuUsageWithoutHostDelta</Target>
93+
<Left>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
94+
<Right>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
95+
<IsBaselineSuppression>true</IsBaselineSuppression>
96+
</Suppression>
97+
<Suppression>
98+
<DiagnosticId>CP0002</DiagnosticId>
99+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_CalculateCpuUsageWithoutHostDelta(System.Boolean)</Target>
100+
<Left>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
101+
<Right>lib/net462/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
102+
<IsBaselineSuppression>true</IsBaselineSuppression>
103+
</Suppression>
104+
<Suppression>
105+
<DiagnosticId>CP0002</DiagnosticId>
106+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_CalculateCpuUsageWithoutHostDelta</Target>
107+
<Left>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
108+
<Right>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
109+
<IsBaselineSuppression>true</IsBaselineSuppression>
110+
</Suppression>
111+
<Suppression>
112+
<DiagnosticId>CP0002</DiagnosticId>
113+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_CalculateCpuUsageWithoutHostDelta(System.Boolean)</Target>
114+
<Left>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
115+
<Right>lib/net8.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
116+
<IsBaselineSuppression>true</IsBaselineSuppression>
117+
</Suppression>
118+
<Suppression>
119+
<DiagnosticId>CP0002</DiagnosticId>
120+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.get_CalculateCpuUsageWithoutHostDelta</Target>
121+
<Left>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
122+
<Right>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
123+
<IsBaselineSuppression>true</IsBaselineSuppression>
124+
</Suppression>
125+
<Suppression>
126+
<DiagnosticId>CP0002</DiagnosticId>
127+
<Target>M:Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceMonitoringOptions.set_CalculateCpuUsageWithoutHostDelta(System.Boolean)</Target>
128+
<Left>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Left>
129+
<Right>lib/net9.0/Microsoft.Extensions.Diagnostics.ResourceMonitoring.dll</Right>
130+
<IsBaselineSuppression>true</IsBaselineSuppression>
131+
</Suppression>
46132
</Suppressions>

src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs

Lines changed: 47 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,25 @@ internal sealed class LinuxUtilizationProvider : ISnapshotProvider
1414
{
1515
private const double One = 1.0;
1616
private const long Hundred = 100L;
17-
private const double CpuLimitThreshold110Percent = 1.1;
1817

19-
// Meters to track CPU utilization threshold exceedances
20-
private readonly Counter<long>? _cpuUtilizationLimit100PercentExceededCounter;
21-
private readonly Counter<long>? _cpuUtilizationLimit110PercentExceededCounter;
22-
23-
private readonly bool _useDeltaNrPeriods;
2418
private readonly object _cpuLocker = new();
2519
private readonly object _memoryLocker = new();
2620
private readonly ILogger<LinuxUtilizationProvider> _logger;
2721
private readonly ILinuxUtilizationParser _parser;
2822
private readonly ulong _memoryLimit;
23+
private readonly long _cpuPeriodsInterval;
2924
private readonly TimeSpan _cpuRefreshInterval;
3025
private readonly TimeSpan _memoryRefreshInterval;
3126
private readonly TimeProvider _timeProvider;
32-
private readonly double _scaleRelativeToCpuLimit;
33-
private readonly double _scaleRelativeToCpuRequest;
3427
private readonly double _scaleRelativeToCpuRequestForTrackerApi;
3528

3629
private DateTimeOffset _refreshAfterCpu;
3730
private DateTimeOffset _refreshAfterMemory;
38-
39-
// Track the actual timestamp when we read CPU values
40-
private DateTimeOffset _lastCpuMeasurementTime;
41-
4231
private double _cpuPercentage = double.NaN;
4332
private double _lastCpuCoresUsed = double.NaN;
4433
private double _memoryPercentage;
4534
private long _previousCgroupCpuTime;
4635
private long _previousHostCpuTime;
47-
private long _cpuUtilizationLimit100PercentExceeded;
48-
private long _cpuUtilizationLimit110PercentExceeded;
49-
private long _cpuPeriodsInterval;
5036
private long _previousCgroupCpuPeriodCounter;
5137
public SystemResources Resources { get; }
5238

@@ -59,7 +45,6 @@ public LinuxUtilizationProvider(IOptions<ResourceMonitoringOptions> options, ILi
5945
DateTimeOffset now = _timeProvider.GetUtcNow();
6046
_cpuRefreshInterval = options.Value.CpuConsumptionRefreshInterval;
6147
_memoryRefreshInterval = options.Value.MemoryConsumptionRefreshInterval;
62-
_useDeltaNrPeriods = options.Value.UseDeltaNrPeriodsForCpuCalculation;
6348
_refreshAfterCpu = now;
6449
_refreshAfterMemory = now;
6550
_memoryLimit = _parser.GetAvailableMemoryInBytes();
@@ -69,8 +54,8 @@ public LinuxUtilizationProvider(IOptions<ResourceMonitoringOptions> options, ILi
6954
float hostCpus = _parser.GetHostCpuCount();
7055
float cpuLimit = _parser.GetCgroupLimitedCpus();
7156
float cpuRequest = _parser.GetCgroupRequestCpu();
72-
_scaleRelativeToCpuLimit = hostCpus / cpuLimit;
73-
_scaleRelativeToCpuRequest = hostCpus / cpuRequest;
57+
float scaleRelativeToCpuLimit = hostCpus / cpuLimit;
58+
float scaleRelativeToCpuRequest = hostCpus / cpuRequest;
7459
_scaleRelativeToCpuRequestForTrackerApi = hostCpus; // the division by cpuRequest is performed later on in the ResourceUtilization class
7560

7661
#pragma warning disable CA2000 // Dispose objects before losing scope
@@ -80,28 +65,23 @@ public LinuxUtilizationProvider(IOptions<ResourceMonitoringOptions> options, ILi
8065
var meter = meterFactory.Create(ResourceUtilizationInstruments.MeterName);
8166
#pragma warning restore CA2000 // Dispose objects before losing scope
8267

83-
if (options.Value.CalculateCpuUsageWithoutHostDelta)
68+
if (options.Value.UseLinuxCpuUsageV2)
8469
{
8570
cpuLimit = _parser.GetCgroupLimitV2();
86-
87-
// Try to get the CPU request from cgroup
8871
cpuRequest = _parser.GetCgroupRequestCpuV2();
8972

9073
// Get Cpu periods interval from cgroup
9174
_cpuPeriodsInterval = _parser.GetCgroupPeriodsIntervalInMicroSecondsV2();
9275
(_previousCgroupCpuTime, _previousCgroupCpuPeriodCounter) = _parser.GetCgroupCpuUsageInNanosecondsAndCpuPeriodsV2();
9376

94-
// Initialize the counters
95-
_cpuUtilizationLimit100PercentExceededCounter = meter.CreateCounter<long>("cpu_utilization_limit_100_percent_exceeded");
96-
_cpuUtilizationLimit110PercentExceededCounter = meter.CreateCounter<long>("cpu_utilization_limit_110_percent_exceeded");
9777
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuLimitUtilization, observeValue: () => CpuUtilizationLimit(cpuLimit), unit: "1");
98-
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuRequestUtilization, observeValue: () => CpuUtilizationWithoutHostDelta() / cpuRequest, unit: "1");
78+
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuRequestUtilization, observeValue: () => CpuUtilizationRequest(cpuRequest), unit: "1");
9979
}
10080
else
10181
{
102-
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuLimitUtilization, observeValue: () => CpuUtilization() * _scaleRelativeToCpuLimit, unit: "1");
103-
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuRequestUtilization, observeValue: () => CpuUtilization() * _scaleRelativeToCpuRequest, unit: "1");
104-
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ProcessCpuUtilization, observeValue: () => CpuUtilization() * _scaleRelativeToCpuRequest, unit: "1");
82+
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuLimitUtilization, observeValue: () => CpuUtilization() * scaleRelativeToCpuLimit, unit: "1");
83+
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuRequestUtilization, observeValue: () => CpuUtilization() * scaleRelativeToCpuRequest, unit: "1");
84+
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ProcessCpuUtilization, observeValue: () => CpuUtilization() * scaleRelativeToCpuRequest, unit: "1");
10585
}
10686

10787
_ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerMemoryLimitUtilization, observeValue: MemoryUtilization, unit: "1");
@@ -115,10 +95,9 @@ public LinuxUtilizationProvider(IOptions<ResourceMonitoringOptions> options, ILi
11595
_logger.SystemResourcesInfo(cpuLimit, cpuRequest, _memoryLimit, _memoryLimit);
11696
}
11797

118-
public double CpuUtilizationWithoutHostDelta()
98+
public double CpuUtilizationV2()
11999
{
120100
DateTimeOffset now = _timeProvider.GetUtcNow();
121-
double actualElapsedNanoseconds = (now - _lastCpuMeasurementTime).TotalNanoseconds;
122101
lock (_cpuLocker)
123102
{
124103
if (now < _refreshAfterCpu)
@@ -127,79 +106,34 @@ public double CpuUtilizationWithoutHostDelta()
127106
}
128107
}
129108

130-
var (cpuUsageTime, cpuPeriodCounter) = _parser.GetCgroupCpuUsageInNanosecondsAndCpuPeriodsV2();
109+
(long cpuUsageTime, long cpuPeriodCounter) = _parser.GetCgroupCpuUsageInNanosecondsAndCpuPeriodsV2();
131110
lock (_cpuLocker)
132111
{
133-
if (now >= _refreshAfterCpu)
112+
if (now < _refreshAfterCpu)
134113
{
135-
long deltaCgroup = cpuUsageTime - _previousCgroupCpuTime;
136-
double coresUsed;
137-
138-
if (_useDeltaNrPeriods)
139-
{
140-
long deltaPeriodCount = cpuPeriodCounter - _previousCgroupCpuPeriodCounter;
141-
long deltaCpuPeriodInNanoseconds = deltaPeriodCount * _cpuPeriodsInterval * 1000;
142-
143-
if (deltaCgroup > 0 && deltaPeriodCount > 0)
144-
{
145-
coresUsed = deltaCgroup / (double)deltaCpuPeriodInNanoseconds;
146-
147-
_logger.CpuUsageDataV2(cpuUsageTime, _previousCgroupCpuTime, deltaCpuPeriodInNanoseconds, coresUsed);
148-
149-
_lastCpuCoresUsed = coresUsed;
150-
_refreshAfterCpu = now.Add(_cpuRefreshInterval);
151-
_previousCgroupCpuTime = cpuUsageTime;
152-
_previousCgroupCpuPeriodCounter = cpuPeriodCounter;
153-
}
154-
}
155-
else
156-
{
157-
if (deltaCgroup > 0)
158-
{
159-
coresUsed = deltaCgroup / actualElapsedNanoseconds;
160-
161-
_logger.CpuUsageDataV2(cpuUsageTime, _previousCgroupCpuTime, actualElapsedNanoseconds, coresUsed);
162-
163-
_lastCpuCoresUsed = coresUsed;
164-
_refreshAfterCpu = now.Add(_cpuRefreshInterval);
165-
_previousCgroupCpuTime = cpuUsageTime;
166-
167-
// Update the timestamp for next calculation
168-
_lastCpuMeasurementTime = now;
169-
}
170-
}
114+
return _lastCpuCoresUsed;
171115
}
172-
}
173116

174-
return _lastCpuCoresUsed;
175-
}
117+
long deltaCgroup = cpuUsageTime - _previousCgroupCpuTime;
118+
long deltaPeriodCount = cpuPeriodCounter - _previousCgroupCpuPeriodCounter;
176119

177-
/// <summary>
178-
/// Calculates CPU utilization relative to the CPU limit.
179-
/// </summary>
180-
/// <param name="cpuLimit">The CPU limit to use for the calculation.</param>
181-
/// <returns>CPU usage as a ratio of the limit.</returns>
182-
public double CpuUtilizationLimit(float cpuLimit)
183-
{
184-
double utilization = CpuUtilizationWithoutHostDelta() / cpuLimit;
120+
if (deltaCgroup <= 0 || deltaPeriodCount <= 0)
121+
{
122+
return _lastCpuCoresUsed;
123+
}
185124

186-
// Increment counter if utilization exceeds 1 (100%)
187-
if (utilization > 1.0)
188-
{
189-
_cpuUtilizationLimit100PercentExceededCounter?.Add(1);
190-
_cpuUtilizationLimit100PercentExceeded++;
191-
_logger.CounterMessage100(_cpuUtilizationLimit100PercentExceeded);
192-
}
125+
long deltaCpuPeriodInNanoseconds = deltaPeriodCount * _cpuPeriodsInterval * 1000;
126+
double coresUsed = deltaCgroup / (double)deltaCpuPeriodInNanoseconds;
193127

194-
// Increment counter if utilization exceeds 110%
195-
if (utilization > CpuLimitThreshold110Percent)
196-
{
197-
_cpuUtilizationLimit110PercentExceededCounter?.Add(1);
198-
_cpuUtilizationLimit110PercentExceeded++;
199-
_logger.CounterMessage110(_cpuUtilizationLimit110PercentExceeded);
128+
_logger.CpuUsageDataV2(cpuUsageTime, _previousCgroupCpuTime, deltaCpuPeriodInNanoseconds, coresUsed);
129+
130+
_lastCpuCoresUsed = coresUsed;
131+
_refreshAfterCpu = now.Add(_cpuRefreshInterval);
132+
_previousCgroupCpuTime = cpuUsageTime;
133+
_previousCgroupCpuPeriodCounter = cpuPeriodCounter;
200134
}
201135

202-
return utilization;
136+
return _lastCpuCoresUsed;
203137
}
204138

205139
public double CpuUtilization()
@@ -219,23 +153,27 @@ public double CpuUtilization()
219153

220154
lock (_cpuLocker)
221155
{
222-
if (now >= _refreshAfterCpu)
156+
if (now < _refreshAfterCpu)
223157
{
224-
long deltaHost = hostCpuTime - _previousHostCpuTime;
225-
long deltaCgroup = cgroupCpuTime - _previousCgroupCpuTime;
226-
227-
if (deltaHost > 0 && deltaCgroup > 0)
228-
{
229-
double percentage = Math.Min(One, (double)deltaCgroup / deltaHost);
158+
return _cpuPercentage;
159+
}
230160

231-
_logger.CpuUsageData(cgroupCpuTime, hostCpuTime, _previousCgroupCpuTime, _previousHostCpuTime, percentage);
161+
long deltaHost = hostCpuTime - _previousHostCpuTime;
162+
long deltaCgroup = cgroupCpuTime - _previousCgroupCpuTime;
232163

233-
_cpuPercentage = percentage;
234-
_refreshAfterCpu = now.Add(_cpuRefreshInterval);
235-
_previousCgroupCpuTime = cgroupCpuTime;
236-
_previousHostCpuTime = hostCpuTime;
237-
}
164+
if (deltaHost <= 0 || deltaCgroup <= 0)
165+
{
166+
return _cpuPercentage;
238167
}
168+
169+
double percentage = Math.Min(One, (double)deltaCgroup / deltaHost);
170+
171+
_logger.CpuUsageData(cgroupCpuTime, hostCpuTime, _previousCgroupCpuTime, _previousHostCpuTime, percentage);
172+
173+
_cpuPercentage = percentage;
174+
_refreshAfterCpu = now.Add(_cpuRefreshInterval);
175+
_previousCgroupCpuTime = cgroupCpuTime;
176+
_previousHostCpuTime = hostCpuTime;
239177
}
240178

241179
return _cpuPercentage;
@@ -288,4 +226,7 @@ public Snapshot GetSnapshot()
288226
userTimeSinceStart: TimeSpan.FromTicks((long)(cgroupTime / Hundred * _scaleRelativeToCpuRequestForTrackerApi)),
289227
memoryUsageInBytes: memoryUsed);
290228
}
229+
230+
private double CpuUtilizationRequest(double cpuRequest) => Math.Min(One, CpuUtilizationV2() / cpuRequest);
231+
private double CpuUtilizationLimit(double cpuLimit) => Math.Min(One, CpuUtilizationV2() / cpuLimit);
291232
}

src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/Log.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,7 @@ public static partial void CpuUsageDataV2(
5050
double actualElapsedNanoseconds,
5151
double cpuCores);
5252

53-
[LoggerMessage(5, LogLevel.Debug,
54-
"CPU utilization exceeded 100%: Counter = {counterValue}")]
55-
public static partial void CounterMessage100(
56-
this ILogger logger,
57-
long counterValue);
58-
59-
[LoggerMessage(6, LogLevel.Debug,
60-
"CPU utilization exceeded 110%: Counter = {counterValue}")]
61-
public static partial void CounterMessage110(
62-
this ILogger logger,
63-
long counterValue);
64-
65-
[LoggerMessage(7, LogLevel.Warning,
53+
[LoggerMessage(5, LogLevel.Warning,
6654
"Error while getting disk stats: Error={errorMessage}")]
6755
public static partial void HandleDiskStatsException(
6856
this ILogger logger,

0 commit comments

Comments
 (0)