From 6396cce86c3e4b32fbcaac2f7afa1ffe869fb594 Mon Sep 17 00:00:00 2001 From: gitmln Date: Thu, 5 Sep 2024 18:05:35 +0200 Subject: [PATCH 1/3] Revert correct Meter name --- .../Linux/LinuxUtilizationProvider.cs | 3 ++- .../Windows/WindowsContainerSnapshotProvider.cs | 3 ++- .../Windows/WindowsSnapshotProvider.cs | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs index 3e2172e9135..b30a0b487b4 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs @@ -13,6 +13,7 @@ internal sealed class LinuxUtilizationProvider : ISnapshotProvider { private const double One = 1.0; private const long Hundred = 100L; + private const string MeterName = "Microsoft.Extensions.Diagnostics.ResourceMonitoring"; private readonly object _cpuLocker = new(); private readonly object _memoryLocker = new(); @@ -62,7 +63,7 @@ public LinuxUtilizationProvider(IOptions options, ILi // We don't dispose the meter because IMeterFactory handles that // An issue on analyzer side: https://github.com/dotnet/roslyn-analyzers/issues/6912 // Related documentation: https://github.com/dotnet/docs/pull/37170 - var meter = meterFactory.Create(nameof(Microsoft.Extensions.Diagnostics.ResourceMonitoring)); + var meter = meterFactory.Create(MeterName); #pragma warning restore CA2000 // Dispose objects before losing scope _ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuLimitUtilization, observeValue: () => CpuUtilization() * _scaleRelativeToCpuLimit, unit: "1"); diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs index 56dbb4ae33a..94db347a8ff 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs @@ -15,6 +15,7 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows; internal sealed class WindowsContainerSnapshotProvider : ISnapshotProvider { private const double Hundred = 100.0d; + private const string MeterName = "Microsoft.Extensions.Diagnostics.ResourceMonitoring"; private readonly Lazy _memoryStatus; @@ -105,7 +106,7 @@ internal WindowsContainerSnapshotProvider( // We don't dispose the meter because IMeterFactory handles that // An issue on analyzer side: https://github.com/dotnet/roslyn-analyzers/issues/6912 // Related documentation: https://github.com/dotnet/docs/pull/37170 - var meter = meterFactory.Create(nameof(Microsoft.Extensions.Diagnostics.ResourceMonitoring)); + var meter = meterFactory.Create(MeterName); #pragma warning restore CA2000 // Dispose objects before losing scope // Container based metrics: diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs index 7104b7b9e5f..592d5db03a3 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs @@ -15,6 +15,7 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows; internal sealed class WindowsSnapshotProvider : ISnapshotProvider { private const double Hundred = 100.0d; + private const string MeterName = "Microsoft.Extensions.Diagnostics.ResourceMonitoring"; public SystemResources Resources { get; } @@ -81,7 +82,7 @@ internal WindowsSnapshotProvider( // We don't dispose the meter because IMeterFactory handles that // An issue on analyzer side: https://github.com/dotnet/roslyn-analyzers/issues/6912 // Related documentation: https://github.com/dotnet/docs/pull/37170 - var meter = meterFactory.Create(nameof(Microsoft.Extensions.Diagnostics.ResourceMonitoring)); + var meter = meterFactory.Create(MeterName); #pragma warning restore CA2000 // Dispose objects before losing scope _ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ProcessCpuUtilization, observeValue: CpuPercentage); From 574e908d502ddfbd6a48f9f87b215078b4bbc30c Mon Sep 17 00:00:00 2001 From: gitmln Date: Fri, 6 Sep 2024 11:55:49 +0200 Subject: [PATCH 2/3] Unit tests for ResourceMonitoring meter name --- .../Linux/LinuxUtilizationProvider.cs | 3 +- .../ResourceUtilizationInstruments.cs | 5 +++ .../WindowsContainerSnapshotProvider.cs | 3 +- .../Windows/WindowsSnapshotProvider.cs | 3 +- .../Helpers/TestMeterFactory.cs | 41 +++++++++++++++++++ .../Linux/LinuxUtilizationProviderTests.cs | 14 +++++++ .../Resources/DummyLinuxUtilizationParser.cs | 18 ++++++++ .../WindowsContainerSnapshotProviderTests.cs | 14 +++++++ .../Windows/WindowsSnapshotProviderTests.cs | 13 ++++++ 9 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Helpers/TestMeterFactory.cs create mode 100644 test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/Resources/DummyLinuxUtilizationParser.cs diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs index b30a0b487b4..d7914104adb 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs @@ -13,7 +13,6 @@ internal sealed class LinuxUtilizationProvider : ISnapshotProvider { private const double One = 1.0; private const long Hundred = 100L; - private const string MeterName = "Microsoft.Extensions.Diagnostics.ResourceMonitoring"; private readonly object _cpuLocker = new(); private readonly object _memoryLocker = new(); @@ -63,7 +62,7 @@ public LinuxUtilizationProvider(IOptions options, ILi // We don't dispose the meter because IMeterFactory handles that // An issue on analyzer side: https://github.com/dotnet/roslyn-analyzers/issues/6912 // Related documentation: https://github.com/dotnet/docs/pull/37170 - var meter = meterFactory.Create(MeterName); + var meter = meterFactory.Create(ResourceUtilizationInstruments.MeterName); #pragma warning restore CA2000 // Dispose objects before losing scope _ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ContainerCpuLimitUtilization, observeValue: () => CpuUtilization() * _scaleRelativeToCpuLimit, unit: "1"); diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationInstruments.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationInstruments.cs index f787ec2ecf4..fe8e508afb2 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationInstruments.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationInstruments.cs @@ -11,6 +11,11 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring; /// internal static class ResourceUtilizationInstruments { + /// + /// The name of the ResourceMonitoring Meter. + /// + public const string MeterName = "Microsoft.Extensions.Diagnostics.ResourceMonitoring"; + /// /// The name of an instrument to retrieve CPU limit consumption of all processes running inside a container or control group in range [0, 1]. /// diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs index 94db347a8ff..3f2c4b8638a 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsContainerSnapshotProvider.cs @@ -15,7 +15,6 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows; internal sealed class WindowsContainerSnapshotProvider : ISnapshotProvider { private const double Hundred = 100.0d; - private const string MeterName = "Microsoft.Extensions.Diagnostics.ResourceMonitoring"; private readonly Lazy _memoryStatus; @@ -106,7 +105,7 @@ internal WindowsContainerSnapshotProvider( // We don't dispose the meter because IMeterFactory handles that // An issue on analyzer side: https://github.com/dotnet/roslyn-analyzers/issues/6912 // Related documentation: https://github.com/dotnet/docs/pull/37170 - var meter = meterFactory.Create(MeterName); + var meter = meterFactory.Create(ResourceUtilizationInstruments.MeterName); #pragma warning restore CA2000 // Dispose objects before losing scope // Container based metrics: diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs index 592d5db03a3..7197499afd9 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsSnapshotProvider.cs @@ -15,7 +15,6 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows; internal sealed class WindowsSnapshotProvider : ISnapshotProvider { private const double Hundred = 100.0d; - private const string MeterName = "Microsoft.Extensions.Diagnostics.ResourceMonitoring"; public SystemResources Resources { get; } @@ -82,7 +81,7 @@ internal WindowsSnapshotProvider( // We don't dispose the meter because IMeterFactory handles that // An issue on analyzer side: https://github.com/dotnet/roslyn-analyzers/issues/6912 // Related documentation: https://github.com/dotnet/docs/pull/37170 - var meter = meterFactory.Create(MeterName); + var meter = meterFactory.Create(ResourceUtilizationInstruments.MeterName); #pragma warning restore CA2000 // Dispose objects before losing scope _ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.ProcessCpuUtilization, observeValue: CpuPercentage); diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Helpers/TestMeterFactory.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Helpers/TestMeterFactory.cs new file mode 100644 index 00000000000..42ac54926c4 --- /dev/null +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Helpers/TestMeterFactory.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics.Metrics; + +namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Test.Helpers; + +internal class TestMeterFactory : IMeterFactory +{ + public List Meters { get; } = new List(); + + public Meter Create(MeterOptions options) + { + var meter = new Meter(options.Name, options.Version, Array.Empty>(), scope: this); + Meters.Add(meter); + + return meter; + } + + public Meter Create(string name) + { + return Create(new MeterOptions(name) + { + Version = null, + Tags = null, + Scope = null + }); + } + + public void Dispose() + { + foreach (var meter in Meters) + { + meter.Dispose(); + } + + Meters.Clear(); + } +} 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 44297768a70..8a9b10ff460 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxUtilizationProviderTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxUtilizationProviderTests.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Test.Helpers; using Microsoft.Extensions.Logging.Testing; using Microsoft.TestUtilities; using Moq; @@ -191,4 +192,17 @@ public Task Provider_EmitsLogRecord() return Verifier.Verify(logRecords).UseDirectory(VerifiedDataDirectory); } + + [Fact] + public void Provider_Creates_Meter_With_Correct_Name() + { + var options = Options.Options.Create(new()); + using var meterFactory = new TestMeterFactory(); + + var parser = new DummyLinuxUtilizationParser(); + _ = new LinuxUtilizationProvider(options, parser, meterFactory); + + var meter = meterFactory.Meters.Single(); + Assert.Equal(ResourceUtilizationInstruments.MeterName, meter.Name); + } } diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/Resources/DummyLinuxUtilizationParser.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/Resources/DummyLinuxUtilizationParser.cs new file mode 100644 index 00000000000..b06b8134a39 --- /dev/null +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/Resources/DummyLinuxUtilizationParser.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Linux; + +namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Linux.Test; + +internal class DummyLinuxUtilizationParser : ILinuxUtilizationParser +{ + public ulong GetAvailableMemoryInBytes() => 1; + public long GetCgroupCpuUsageInNanoseconds() => 0; + public float GetCgroupLimitedCpus() => 1; + public float GetCgroupRequestCpu() => 1; + public ulong GetHostAvailableMemory() => 0; + public float GetHostCpuCount() => 1; + public long GetHostCpuUsageInNanoseconds() => 0; + public ulong GetMemoryUsageInBytes() => 0; +} \ No newline at end of file diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs index 3310f70d798..d2642cc8f65 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs @@ -3,8 +3,10 @@ using System; using System.Diagnostics.Metrics; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Diagnostics.Metrics.Testing; +using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Test.Helpers; using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows.Interop; using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Time.Testing; @@ -322,4 +324,16 @@ public Task SnapshotProvider_EmitsLogRecord() return Verifier.Verify(logRecords).UniqueForRuntime().UseDirectory(VerifiedDataDirectory); } + + [Fact] + public void Provider_Creates_Meter_With_Correct_Name() + { + var options = Options.Options.Create(new()); + using var meterFactory = new TestMeterFactory(); + + _ = new WindowsContainerSnapshotProvider(_logger, meterFactory, options); + + var meter = meterFactory.Meters.Single(); + Assert.Equal(ResourceUtilizationInstruments.MeterName, meter.Name); + } } diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs index aa53a431b06..a7d53882218 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs @@ -3,8 +3,10 @@ using System; using System.Diagnostics.Metrics; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Diagnostics.Metrics.Testing; +using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Test.Helpers; using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows.Interop; using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Options; @@ -155,4 +157,15 @@ public void Provider_Returns_MemoryConsumption() var usage = WindowsSnapshotProvider.GetMemoryUsageInBytes(); Assert.InRange(usage, 0, long.MaxValue); } + + [Fact] + public void Provider_Creates_Meter_With_Correct_Name() + { + using var meterFactory = new TestMeterFactory(); + + _ = new WindowsSnapshotProvider(_fakeLogger, meterFactory, _options); + + var meter = meterFactory.Meters.Single(); + Assert.Equal(ResourceUtilizationInstruments.MeterName, meter.Name); + } } From 4d1d29c23c7644dd58bb1e14c6f7620f3c254a6f Mon Sep 17 00:00:00 2001 From: gitmln Date: Fri, 6 Sep 2024 12:30:22 +0200 Subject: [PATCH 3/3] Fixed Windows test on Linuz --- .../Windows/WindowsContainerSnapshotProviderTests.cs | 10 +++++++++- .../Windows/WindowsSnapshotProviderTests.cs | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs index d2642cc8f65..c013c77d7b4 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsContainerSnapshotProviderTests.cs @@ -331,7 +331,15 @@ public void Provider_Creates_Meter_With_Correct_Name() var options = Options.Options.Create(new()); using var meterFactory = new TestMeterFactory(); - _ = new WindowsContainerSnapshotProvider(_logger, meterFactory, options); + _ = new WindowsContainerSnapshotProvider( + _memoryInfoMock.Object, + _systemInfoMock.Object, + _processInfoMock.Object, + _logger, + meterFactory, + () => _jobHandleMock.Object, + new FakeTimeProvider(), + new()); var meter = meterFactory.Meters.Single(); Assert.Equal(ResourceUtilizationInstruments.MeterName, meter.Name); diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs index a7d53882218..6a76d8a95f4 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsSnapshotProviderTests.cs @@ -158,7 +158,7 @@ public void Provider_Returns_MemoryConsumption() Assert.InRange(usage, 0, long.MaxValue); } - [Fact] + [ConditionalFact] public void Provider_Creates_Meter_With_Correct_Name() { using var meterFactory = new TestMeterFactory();