Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd671e88

Browse files
evgenyfedorov2evgenyfedorov2
authored and
evgenyfedorov2
committed
Add memory usage metric
1 parent294a33d commitd671e88

File tree

9 files changed

+185
-37
lines changed

9 files changed

+185
-37
lines changed

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

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ internal sealed class LinuxUtilizationProvider : ISnapshotProvider
3737
privateDateTimeOffset_refreshAfterMemory;
3838
privatedouble_cpuPercentage=double.NaN;
3939
privatedouble_lastCpuCoresUsed=double.NaN;
40-
privatedouble_memoryPercentage;
40+
privateulong_memoryUsage;
4141
privatelong_previousCgroupCpuTime;
4242
privatelong_previousHostCpuTime;
4343
privatelong_previousCgroupCpuPeriodCounter;
@@ -116,12 +116,18 @@ public LinuxUtilizationProvider(IOptions<ResourceMonitoringOptions> options, ILi
116116

117117
_=meter.CreateObservableGauge(
118118
name:ResourceUtilizationInstruments.ContainerMemoryLimitUtilization,
119-
observeValues:()=>GetMeasurementWithRetry(MemoryUtilization),
119+
observeValues:()=>GetMeasurementWithRetry(MemoryPercentage),
120120
unit:"1");
121121

122+
_=meter.CreateObservableUpDownCounter(
123+
name:ResourceUtilizationInstruments.ContainerMemoryUtilization,
124+
observeValues:()=>GetMeasurementWithRetry(()=>(long)MemoryUtilization()),
125+
unit:"By",
126+
description:"Memory usage of the container.");
127+
122128
_=meter.CreateObservableGauge(
123129
name:ResourceUtilizationInstruments.ProcessMemoryUtilization,
124-
observeValues:()=>GetMeasurementWithRetry(MemoryUtilization),
130+
observeValues:()=>GetMeasurementWithRetry(MemoryPercentage),
125131
unit:"1");
126132

127133
// cpuRequest is a CPU request (aka guaranteed number of CPU units) for pod, for host its 1 core
@@ -216,34 +222,32 @@ public double CpuUtilization()
216222
return_cpuPercentage;
217223
}
218224

219-
publicdoubleMemoryUtilization()
225+
publiculongMemoryUtilization()
220226
{
221227
DateTimeOffsetnow=_timeProvider.GetUtcNow();
222228

223229
lock(_memoryLocker)
224230
{
225231
if(now<_refreshAfterMemory)
226232
{
227-
return_memoryPercentage;
233+
return_memoryUsage;
228234
}
229235
}
230236

231-
ulongmemoryUsed=_parser.GetMemoryUsageInBytes();
237+
ulongmemoryUsage=_parser.GetMemoryUsageInBytes();
232238

233239
lock(_memoryLocker)
234240
{
235241
if(now>=_refreshAfterMemory)
236242
{
237-
doublememoryPercentage=Math.Min(One,(double)memoryUsed/_memoryLimit);
238-
239-
_memoryPercentage=memoryPercentage;
243+
_memoryUsage=memoryUsage;
240244
_refreshAfterMemory=now.Add(_memoryRefreshInterval);
241245
}
242246
}
243247

244-
_logger.MemoryUsageData(memoryUsed,_memoryLimit,_memoryPercentage);
248+
_logger.MemoryUsageData(_memoryUsage);
245249

246-
return_memoryPercentage;
250+
return_memoryUsage;
247251
}
248252

249253
/// <remarks>
@@ -264,14 +268,24 @@ public Snapshot GetSnapshot()
264268
memoryUsageInBytes:memoryUsed);
265269
}
266270

267-
privateMeasurement<double>[]GetMeasurementWithRetry(Func<double>func)
271+
privatedoubleMemoryPercentage()
272+
{
273+
ulongmemoryUsage=MemoryUtilization();
274+
doublememoryPercentage=Math.Min(One,(double)memoryUsage/_memoryLimit);
275+
276+
_logger.MemoryPercentageData(memoryUsage,_memoryLimit,memoryPercentage);
277+
returnmemoryPercentage;
278+
}
279+
280+
privateMeasurement<T>[]GetMeasurementWithRetry<T>(Func<T>func)
281+
whereT:struct
268282
{
269-
if(!TryGetValueWithRetry(func,outdoublevalue))
283+
if(!TryGetValueWithRetry(func,outTvalue))
270284
{
271-
returnArray.Empty<Measurement<double>>();
285+
returnArray.Empty<Measurement<T>>();
272286
}
273287

274-
returnnew[]{newMeasurement<double>(value)};
288+
returnnew[]{newMeasurement<T>(value)};
275289
}
276290

277291
privateboolTryGetValueWithRetry<T>(Func<T>func,outTvalue)

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public static partial void CpuUsageData(
2323
doublecpuPercentage);
2424

2525
[LoggerMessage(2,LogLevel.Debug,
26-
"Computed memoryusage with MemoryUsedInBytes = {memoryUsed}, MemoryLimit = {memoryLimit}, MemoryPercentage = {memoryPercentage}.")]
27-
publicstaticpartialvoidMemoryUsageData(
26+
"Computed memorypercentage with MemoryUsedInBytes = {memoryUsed}, MemoryLimit = {memoryLimit}, MemoryPercentage = {memoryPercentage}.")]
27+
publicstaticpartialvoidMemoryPercentageData(
2828
thisILoggerlogger,
2929
ulongmemoryUsed,
3030
doublememoryLimit,
@@ -55,4 +55,10 @@ public static partial void CpuUsageDataV2(
5555
publicstaticpartialvoidHandleDiskStatsException(
5656
thisILoggerlogger,
5757
stringerrorMessage);
58+
59+
[LoggerMessage(6,LogLevel.Debug,
60+
"Computed memory usage with MemoryUsedInBytes = {memoryUsed}.")]
61+
publicstaticpartialvoidMemoryUsageData(
62+
thisILoggerlogger,
63+
ulongmemoryUsed);
5864
}

‎src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/Log.cs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static partial void CpuUsageData(
2727

2828
[LoggerMessage(4,LogLevel.Debug,
2929
"Computed memory usage with CurrentMemoryUsage = {currentMemoryUsage}, TotalMemory = {totalMemory}, MemoryPercentage = {memoryPercentage}.")]
30-
publicstaticpartialvoidMemoryUsageData(
30+
publicstaticpartialvoidMemoryPercentageData(
3131
thisILoggerlogger,
3232
ulongcurrentMemoryUsage,
3333
doubletotalMemory,
@@ -60,4 +60,10 @@ public static partial void DiskIoPerfCounterException(
6060
thisILoggerlogger,
6161
stringcounterName,
6262
stringerrorMessage);
63+
64+
[LoggerMessage(8,LogLevel.Debug,
65+
"Computed memory usage = {currentMemoryUsage}.")]
66+
publicstaticpartialvoidMemoryUsageData(
67+
thisILoggerlogger,
68+
ulongcurrentMemoryUsage);
6369
}

‎src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs‎

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ internal sealed class WindowsContainerSnapshotProvider : ISnapshotProvider
4343
privateDateTimeOffset_refreshAfterCpu;
4444
privateDateTimeOffset_refreshAfterMemory;
4545
privatedouble_cpuPercentage=double.NaN;
46-
privatedouble_memoryPercentage;
46+
privateulong_memoryUsage;
4747

4848
publicSystemResourcesResources{get;}
4949

@@ -116,13 +116,34 @@ internal WindowsContainerSnapshotProvider(
116116
#pragma warning restoreCA2000// Dispose objects before losing scope
117117

118118
// Container based metrics:
119-
_=meter.CreateObservableCounter(name:ResourceUtilizationInstruments.ContainerCpuTime,observeValues:GetCpuTime,unit:"s",description:"CPU time used by the container.");
120-
_=meter.CreateObservableGauge(name:ResourceUtilizationInstruments.ContainerCpuLimitUtilization,observeValue:CpuPercentage);
121-
_=meter.CreateObservableGauge(name:ResourceUtilizationInstruments.ContainerMemoryLimitUtilization,observeValue:()=>MemoryPercentage(()=>_processInfo.GetMemoryUsage()));
119+
_=meter.CreateObservableCounter(
120+
name:ResourceUtilizationInstruments.ContainerCpuTime,
121+
observeValues:GetCpuTime,
122+
unit:"s",
123+
description:"CPU time used by the container.");
124+
125+
_=meter.CreateObservableGauge(
126+
name:ResourceUtilizationInstruments.ContainerCpuLimitUtilization,
127+
observeValue:CpuPercentage);
128+
129+
_=meter.CreateObservableGauge(
130+
name:ResourceUtilizationInstruments.ContainerMemoryLimitUtilization,
131+
observeValue:()=>MemoryPercentage(()=>_processInfo.GetMemoryUsage()));
132+
133+
_=meter.CreateObservableUpDownCounter(
134+
name:ResourceUtilizationInstruments.ContainerMemoryUtilization,
135+
observeValue:()=>(long)MemoryUsage(()=>_processInfo.GetMemoryUsage()),
136+
unit:"By",
137+
description:"Memory usage of the container.");
122138

123139
// Process based metrics:
124-
_=meter.CreateObservableGauge(name:ResourceUtilizationInstruments.ProcessCpuUtilization,observeValue:CpuPercentage);
125-
_=meter.CreateObservableGauge(name:ResourceUtilizationInstruments.ProcessMemoryUtilization,observeValue:()=>MemoryPercentage(()=>_processInfo.GetCurrentProcessMemoryUsage()));
140+
_=meter.CreateObservableGauge(
141+
name:ResourceUtilizationInstruments.ProcessCpuUtilization,
142+
observeValue:CpuPercentage);
143+
144+
_=meter.CreateObservableGauge(
145+
name:ResourceUtilizationInstruments.ProcessMemoryUtilization,
146+
observeValue:()=>MemoryPercentage(()=>_processInfo.GetCurrentProcessMemoryUsage()));
126147
}
127148

128149
publicSnapshotGetSnapshot()
@@ -186,14 +207,23 @@ private ulong GetMemoryLimit(IJobHandle jobHandle)
186207
}
187208

188209
privatedoubleMemoryPercentage(Func<ulong>getMemoryUsage)
210+
{
211+
ulongmemoryUsage=MemoryUsage(getMemoryUsage);
212+
doublememoryPercentage=Math.Min(_metricValueMultiplier,memoryUsage/_memoryLimit*_metricValueMultiplier);
213+
214+
_logger.MemoryPercentageData(memoryUsage,_memoryLimit,memoryPercentage);
215+
returnmemoryPercentage;
216+
}
217+
218+
privateulongMemoryUsage(Func<ulong>getMemoryUsage)
189219
{
190220
DateTimeOffsetnow=_timeProvider.GetUtcNow();
191221

192222
lock(_memoryLocker)
193223
{
194224
if(now<_refreshAfterMemory)
195225
{
196-
return_memoryPercentage;
226+
return_memoryUsage;
197227
}
198228
}
199229

@@ -203,14 +233,12 @@ private double MemoryPercentage(Func<ulong> getMemoryUsage)
203233
{
204234
if(now>=_refreshAfterMemory)
205235
{
206-
// Don't change calculation order, otherwise we loose some precision:
207-
_memoryPercentage=Math.Min(_metricValueMultiplier,memoryUsage/_memoryLimit*_metricValueMultiplier);
236+
_memoryUsage=memoryUsage;
208237
_refreshAfterMemory=now.Add(_memoryRefreshInterval);
209238
}
210239

211-
_logger.MemoryUsageData(memoryUsage,_memoryLimit,_memoryPercentage);
212-
213-
return_memoryPercentage;
240+
_logger.MemoryUsageData(_memoryUsage);
241+
return_memoryUsage;
214242
}
215243
}
216244

‎src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private double MemoryPercentage()
144144
_refreshAfterMemory=now.Add(_memoryRefreshInterval);
145145
}
146146

147-
_logger.MemoryUsageData((ulong)currentMemoryUsage,_totalMemory,_memoryPercentage);
147+
_logger.MemoryPercentageData((ulong)currentMemoryUsage,_totalMemory,_memoryPercentage);
148148

149149
return_memoryPercentage;
150150
}

‎src/Shared/Instruments/ResourceUtilizationInstruments.cs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ internal static class ResourceUtilizationInstruments
5050
/// </remarks>
5151
publicconststringContainerMemoryLimitUtilization="container.memory.limit.utilization";
5252

53+
/// <summary>
54+
/// The name of an instrument to retrieve memory consumption of all processes running inside a container or control group in range <c>[0, 1]</c>.
55+
/// </summary>
56+
/// <remarks>
57+
/// The type of an instrument is <see cref="System.Diagnostics.Metrics.ObservableGauge{T}"/>.
58+
/// </remarks>
59+
publicconststringContainerMemoryUtilization="container.memory.utilization";
60+
5361
/// <summary>
5462
/// The name of an instrument to retrieve CPU consumption share of the running process in range <c>[0, 1]</c>.
5563
/// </summary>

‎test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ public Task ResourceUtilizationTracker_And_Metrics_Report_Same_Values_With_Cgrou
223223
listener.InstrumentPublished=(Instrumentinstrument,MeterListenermeterListener)
224224
=>OnInstrumentPublished(instrument,meterListener,meterScope);
225225
listener.SetMeasurementEventCallback<double>((m,f,tags,_)
226-
=>OnMeasurementReceived(m,f,tags,refcpuUserTime,refcpuKernelTime,refcpuFromGauge,refcpuLimitFromGauge,refcpuRequestFromGauge,refmemoryFromGauge,refmemoryLimitFromGauge));
226+
=>OnMeasurementReceived(m,f,tags,refcpuUserTime,refcpuKernelTime,refcpuFromGauge,refcpuLimitFromGauge,
227+
refcpuRequestFromGauge,refmemoryFromGauge,refmemoryLimitFromGauge));
227228
listener.Start();
228229

229230
usingvarhost=FakeHost.CreateBuilder()
@@ -302,13 +303,24 @@ public Task ResourceUtilizationTracker_And_Metrics_Report_Same_Values_With_Cgrou
302303
varcpuRequestFromGauge=0.0d;
303304
varmemoryFromGauge=0.0d;
304305
varmemoryLimitFromGauge=0.0d;
306+
longmemoryUsageFromGauge=0;
305307
usingvare=newManualResetEventSlim();
306308

307309
object?meterScope=null;
308310
listener.InstrumentPublished=(Instrumentinstrument,MeterListenermeterListener)
309311
=>OnInstrumentPublished(instrument,meterListener,meterScope);
310312
listener.SetMeasurementEventCallback<double>((m,f,tags,_)
311-
=>OnMeasurementReceived(m,f,tags,refcpuUserTime,refcpuKernelTime,refcpuFromGauge,refcpuLimitFromGauge,refcpuRequestFromGauge,refmemoryFromGauge,refmemoryLimitFromGauge));
313+
=>OnMeasurementReceived(
314+
m,f,tags,refcpuUserTime,refcpuKernelTime,refcpuFromGauge,refcpuLimitFromGauge,
315+
refcpuRequestFromGauge,refmemoryFromGauge,refmemoryLimitFromGauge));
316+
listener.SetMeasurementEventCallback<long>((instrument,value,tags,_)
317+
=>
318+
{
319+
if(instrument.Name==ResourceUtilizationInstruments.ContainerMemoryUtilization)
320+
{
321+
memoryUsageFromGauge=value;
322+
}
323+
});
312324
listener.Start();
313325

314326
usingvarhost=FakeHost.CreateBuilder()
@@ -355,6 +367,7 @@ public Task ResourceUtilizationTracker_And_Metrics_Report_Same_Values_With_Cgrou
355367

356368
Assert.Equal(1,roundedCpuUsedPercentage);
357369
Assert.Equal(50,utilization.MemoryUsedPercentage);
370+
Assert.Equal(524288,memoryUsageFromGauge);
358371
Assert.Equal(0.5,cpuLimitFromGauge*100);
359372
Assert.Equal(roundedCpuUsedPercentage,Math.Round(cpuRequestFromGauge*100));
360373
Assert.Equal(utilization.MemoryUsedPercentage,memoryLimitFromGauge*100);
@@ -455,7 +468,8 @@ private static void OnInstrumentPublished(Instrument instrument, MeterListener m
455468
instrument.Name==ResourceUtilizationInstruments.ContainerCpuTime||
456469
instrument.Name==ResourceUtilizationInstruments.ContainerCpuRequestUtilization||
457470
instrument.Name==ResourceUtilizationInstruments.ContainerCpuLimitUtilization||
458-
instrument.Name==ResourceUtilizationInstruments.ContainerMemoryLimitUtilization)
471+
instrument.Name==ResourceUtilizationInstruments.ContainerMemoryLimitUtilization||
472+
instrument.Name==ResourceUtilizationInstruments.ContainerMemoryUtilization)
459473
{
460474
meterListener.EnableMeasurementEvents(instrument);
461475
}

‎test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxUtilizationProviderTests.cs‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,18 @@ public void Provider_Registers_Instruments()
7272
}
7373
});
7474

75+
listener.SetMeasurementEventCallback<long>((instrument,value,_,_)=>
76+
{
77+
if(ReferenceEquals(meter,instrument.Meter))
78+
{
79+
samples.Add((instrument,value));
80+
}
81+
});
82+
7583
listener.Start();
7684
listener.RecordObservableInstruments();
7785

78-
Assert.Equal(5,samples.Count);
86+
Assert.Equal(6,samples.Count);
7987

8088
Assert.Contains(samples, x=>x.instrument.Name==ResourceUtilizationInstruments.ContainerCpuLimitUtilization);
8189
Assert.True(double.IsNaN(samples.Single(i=>i.instrument.Name==ResourceUtilizationInstruments.ContainerCpuLimitUtilization).value));
@@ -86,6 +94,9 @@ public void Provider_Registers_Instruments()
8694
Assert.Contains(samples, x=>x.instrument.Name==ResourceUtilizationInstruments.ContainerMemoryLimitUtilization);
8795
Assert.Equal(0.5,samples.Single(i=>i.instrument.Name==ResourceUtilizationInstruments.ContainerMemoryLimitUtilization).value);
8896

97+
Assert.Contains(samples, x=>x.instrument.Name==ResourceUtilizationInstruments.ContainerMemoryUtilization);
98+
Assert.Equal(524288,samples.Single(i=>i.instrument.Name==ResourceUtilizationInstruments.ContainerMemoryUtilization).value);
99+
89100
Assert.Contains(samples, x=>x.instrument.Name==ResourceUtilizationInstruments.ProcessCpuUtilization);
90101
Assert.True(double.IsNaN(samples.Single(i=>i.instrument.Name==ResourceUtilizationInstruments.ProcessCpuUtilization).value));
91102

@@ -359,7 +370,7 @@ public void Provider_GetMeasurementWithRetry_UnhandledException_DoesNotBlockFutu
359370
parserMock.Setup(p=>p.GetMemoryUsageInBytes()).Returns(()=>
360371
{
361372
callCount++;
362-
if(callCount<=2)
373+
if(callCount<=3)
363374
{
364375
thrownewInvalidOperationException("Simulated unhandled exception");
365376
}
@@ -403,6 +414,6 @@ public void Provider_GetMeasurementWithRetry_UnhandledException_DoesNotBlockFutu
403414
varmetric=samples.SingleOrDefault(x=>x.instrument.Name==ResourceUtilizationInstruments.ProcessMemoryUtilization);
404415
Assert.Equal(1234f/2000f,metric.value,0.01f);
405416

406-
parserMock.Verify(p=>p.GetMemoryUsageInBytes(),Times.Exactly(3));
417+
parserMock.Verify(p=>p.GetMemoryUsageInBytes(),Times.Exactly(4));
407418
}
408419
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp