diff --git a/eng/Dependencies.props b/eng/Dependencies.props
index 0413b558a486..e6807a616d9c 100644
--- a/eng/Dependencies.props
+++ b/eng/Dependencies.props
@@ -62,6 +62,7 @@ and are generated based on the last package release.
+
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 9d277cc1687d..02f78763f006 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -41,288 +41,288 @@
https://github.com/dotnet/efcore
532482d370026338ce670d4aeafa54b906e2defe
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
https://github.com/dotnet/source-build-externals
06913fc4c3fcb0065ee390d135fb766870d2c38a
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
https://github.com/dotnet/xdt
@@ -355,9 +355,9 @@
-
+
https://github.com/dotnet/runtime
- 815953a12c822847095a843d69c610a9f895ae3f
+ edfe49168f3e6f3d30237a0afeabf5dcae2abad5
https://github.com/dotnet/arcade
@@ -385,6 +385,10 @@
https://github.com/dotnet/arcade
e2334b2be36919347923d0ec872a46acddb1e385
+
+ https://github.com/dotnet/extensions
+ a0e9c8794e3e0ba27033a9f54a545385228d0876
+
https://github.com/nuget/nuget.client
8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8
diff --git a/eng/Versions.props b/eng/Versions.props
index 8055c47b6bcb..2ad4f9c7d18b 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -63,77 +63,79 @@
-->
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
- 8.0.0-preview.6.23318.9
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+ 8.0.0-preview.6.23323.4
+
+ 8.0.0-preview.6.23320.3
8.0.0-preview.6.23321.3
8.0.0-preview.6.23321.3
diff --git a/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs b/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs
index 34850626e089..f9efe83a2716 100644
--- a/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs
+++ b/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
-using System.Diagnostics.Metrics;
using System.Diagnostics.Tracing;
using System.Reflection;
using Microsoft.AspNetCore.Http;
@@ -12,6 +11,7 @@
using Microsoft.Extensions.Diagnostics.Metrics;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
using Moq;
namespace Microsoft.AspNetCore.Hosting.Tests;
@@ -52,10 +52,10 @@ public async Task EventCountersAndMetricsValues()
var hostingApplication1 = CreateApplication(out var features1, eventSource: hostingEventSource, meterFactory: testMeterFactory1);
var hostingApplication2 = CreateApplication(out var features2, eventSource: hostingEventSource, meterFactory: testMeterFactory2);
- using var currentRequestsRecorder1 = new InstrumentRecorder(testMeterFactory1, HostingMetrics.MeterName, "http-server-current-requests");
- using var currentRequestsRecorder2 = new InstrumentRecorder(testMeterFactory2, HostingMetrics.MeterName, "http-server-current-requests");
- using var requestDurationRecorder1 = new InstrumentRecorder(testMeterFactory1, HostingMetrics.MeterName, "http-server-request-duration");
- using var requestDurationRecorder2 = new InstrumentRecorder(testMeterFactory2, HostingMetrics.MeterName, "http-server-request-duration");
+ using var currentRequestsRecorder1 = new MetricCollector(testMeterFactory1, HostingMetrics.MeterName, "http-server-current-requests");
+ using var currentRequestsRecorder2 = new MetricCollector(testMeterFactory2, HostingMetrics.MeterName, "http-server-current-requests");
+ using var requestDurationRecorder1 = new MetricCollector(testMeterFactory1, HostingMetrics.MeterName, "http-server-request-duration");
+ using var requestDurationRecorder2 = new MetricCollector(testMeterFactory2, HostingMetrics.MeterName, "http-server-request-duration");
// Act/Assert 1
var context1 = hostingApplication1.CreateContext(features1);
@@ -74,15 +74,15 @@ public async Task EventCountersAndMetricsValues()
Assert.Equal(0, await currentRequestValues.FirstOrDefault(v => v == 0));
Assert.Equal(0, await failedRequestValues.FirstOrDefault(v => v == 0));
- Assert.Collection(currentRequestsRecorder1.GetMeasurements(),
+ Assert.Collection(currentRequestsRecorder1.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value));
- Assert.Collection(currentRequestsRecorder2.GetMeasurements(),
+ Assert.Collection(currentRequestsRecorder2.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value));
- Assert.Collection(requestDurationRecorder1.GetMeasurements(),
+ Assert.Collection(requestDurationRecorder1.GetMeasurementSnapshot(),
m => Assert.True(m.Value > 0));
- Assert.Collection(requestDurationRecorder2.GetMeasurements(),
+ Assert.Collection(requestDurationRecorder2.GetMeasurementSnapshot(),
m => Assert.True(m.Value > 0));
// Act/Assert 2
@@ -105,20 +105,20 @@ public async Task EventCountersAndMetricsValues()
Assert.Equal(0, await currentRequestValues.FirstOrDefault(v => v == 0));
Assert.Equal(2, await failedRequestValues.FirstOrDefault(v => v == 2));
- Assert.Collection(currentRequestsRecorder1.GetMeasurements(),
+ Assert.Collection(currentRequestsRecorder1.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value));
- Assert.Collection(currentRequestsRecorder2.GetMeasurements(),
+ Assert.Collection(currentRequestsRecorder2.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value));
- Assert.Collection(requestDurationRecorder1.GetMeasurements(),
+ Assert.Collection(requestDurationRecorder1.GetMeasurementSnapshot(),
m => Assert.True(m.Value > 0),
m => Assert.True(m.Value > 0));
- Assert.Collection(requestDurationRecorder2.GetMeasurements(),
+ Assert.Collection(requestDurationRecorder2.GetMeasurementSnapshot(),
m => Assert.True(m.Value > 0),
m => Assert.True(m.Value > 0));
}
diff --git a/src/Hosting/Hosting/test/HostingMetricsTests.cs b/src/Hosting/Hosting/test/HostingMetricsTests.cs
index 9fedea8f0807..33598ec8abce 100644
--- a/src/Hosting/Hosting/test/HostingMetricsTests.cs
+++ b/src/Hosting/Hosting/test/HostingMetricsTests.cs
@@ -11,6 +11,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Metrics;
using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
namespace Microsoft.AspNetCore.Hosting.Tests;
@@ -25,9 +26,9 @@ public void MultipleRequests()
var httpContext = new DefaultHttpContext();
var meter = meterFactory.Meters.Single();
- using var requestDurationRecorder = new InstrumentRecorder(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
- using var currentRequestsRecorder = new InstrumentRecorder(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
- using var unhandledRequestsRecorder = new InstrumentRecorder(meterFactory, HostingMetrics.MeterName, "http-server-unhandled-requests");
+ using var requestDurationCollector = new MetricCollector(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
+ using var currentRequestsCollector = new MetricCollector(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
+ using var unhandledRequestsCollector = new MetricCollector(meterFactory, HostingMetrics.MeterName, "http-server-unhandled-requests");
// Act/Assert
Assert.Equal(HostingMetrics.MeterName, meter.Name);
@@ -39,10 +40,10 @@ public void MultipleRequests()
context1.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
hostingApplication.DisposeContext(context1, null);
- Assert.Collection(currentRequestsRecorder.GetMeasurements(),
+ Assert.Collection(currentRequestsCollector.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value));
- Assert.Collection(requestDurationRecorder.GetMeasurements(),
+ Assert.Collection(requestDurationCollector.GetMeasurementSnapshot(),
m => AssertRequestDuration(m, HttpProtocol.Http11, StatusCodes.Status200OK));
// Request 2 (after failure)
@@ -51,12 +52,12 @@ public void MultipleRequests()
context2.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
hostingApplication.DisposeContext(context2, new InvalidOperationException("Test error"));
- Assert.Collection(currentRequestsRecorder.GetMeasurements(),
+ Assert.Collection(currentRequestsCollector.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value));
- Assert.Collection(requestDurationRecorder.GetMeasurements(),
+ Assert.Collection(requestDurationCollector.GetMeasurementSnapshot(),
m => AssertRequestDuration(m, HttpProtocol.Http11, StatusCodes.Status200OK),
m => AssertRequestDuration(m, HttpProtocol.Http2, StatusCodes.Status500InternalServerError, exceptionName: "System.InvalidOperationException"));
@@ -66,37 +67,37 @@ public void MultipleRequests()
context3.HttpContext.Items["__RequestUnhandled"] = true;
context3.HttpContext.Response.StatusCode = StatusCodes.Status404NotFound;
- Assert.Collection(currentRequestsRecorder.GetMeasurements(),
+ Assert.Collection(currentRequestsCollector.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value),
m => Assert.Equal(1, m.Value));
- Assert.Collection(requestDurationRecorder.GetMeasurements(),
+ Assert.Collection(requestDurationCollector.GetMeasurementSnapshot(),
m => AssertRequestDuration(m, HttpProtocol.Http11, StatusCodes.Status200OK),
m => AssertRequestDuration(m, HttpProtocol.Http2, StatusCodes.Status500InternalServerError, exceptionName: "System.InvalidOperationException"));
hostingApplication.DisposeContext(context3, null);
- Assert.Collection(currentRequestsRecorder.GetMeasurements(),
+ Assert.Collection(currentRequestsCollector.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value),
m => Assert.Equal(1, m.Value),
m => Assert.Equal(-1, m.Value));
- Assert.Collection(requestDurationRecorder.GetMeasurements(),
+ Assert.Collection(requestDurationCollector.GetMeasurementSnapshot(),
m => AssertRequestDuration(m, HttpProtocol.Http11, StatusCodes.Status200OK),
m => AssertRequestDuration(m, HttpProtocol.Http2, StatusCodes.Status500InternalServerError, exceptionName: "System.InvalidOperationException"),
m => AssertRequestDuration(m, HttpProtocol.Http3, StatusCodes.Status404NotFound));
- Assert.Collection(unhandledRequestsRecorder.GetMeasurements(),
+ Assert.Collection(unhandledRequestsCollector.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value));
- static void AssertRequestDuration(Measurement measurement, string protocol, int statusCode, string exceptionName = null)
+ static void AssertRequestDuration(CollectedMeasurement measurement, string protocol, int statusCode, string exceptionName = null)
{
Assert.True(measurement.Value > 0);
- Assert.Equal(protocol, (string)measurement.Tags.ToArray().Single(t => t.Key == "protocol").Value);
- Assert.Equal(statusCode, (int)measurement.Tags.ToArray().Single(t => t.Key == "status-code").Value);
+ Assert.Equal(protocol, (string)measurement.Tags["protocol"]);
+ Assert.Equal(statusCode, (int)measurement.Tags["status-code"]);
if (exceptionName == null)
{
Assert.DoesNotContain(measurement.Tags.ToArray(), t => t.Key == "exception-name");
@@ -132,8 +133,8 @@ public async Task StartListeningDuringRequest_NotMeasured()
await syncPoint.WaitForSyncPoint().DefaultTimeout();
- using var requestDurationRecorder = new InstrumentRecorder(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
- using var currentRequestsRecorder = new InstrumentRecorder(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
+ using var requestDurationCollector = new MetricCollector(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
+ using var currentRequestsCollector = new MetricCollector(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
context1.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
syncPoint.Continue();
@@ -141,8 +142,8 @@ public async Task StartListeningDuringRequest_NotMeasured()
hostingApplication.DisposeContext(context1, null);
- Assert.Empty(currentRequestsRecorder.GetMeasurements());
- Assert.Empty(requestDurationRecorder.GetMeasurements());
+ Assert.Empty(currentRequestsCollector.GetMeasurementSnapshot());
+ Assert.Empty(requestDurationCollector.GetMeasurementSnapshot());
}
[Fact]
@@ -154,8 +155,8 @@ public void IHttpMetricsTagsFeatureNotUsedFromFeatureCollection()
var httpContext = new DefaultHttpContext();
var meter = meterFactory.Meters.Single();
- using var requestDurationRecorder = new InstrumentRecorder(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
- using var currentRequestsRecorder = new InstrumentRecorder(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
+ using var requestDurationCollector = new MetricCollector(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
+ using var currentRequestsCollector = new MetricCollector(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
// Act/Assert
Assert.Equal(HostingMetrics.MeterName, meter.Name);
diff --git a/src/Hosting/Hosting/test/Microsoft.AspNetCore.Hosting.Tests.csproj b/src/Hosting/Hosting/test/Microsoft.AspNetCore.Hosting.Tests.csproj
index 0fc87b4ba5c3..19285bbe7ec3 100644
--- a/src/Hosting/Hosting/test/Microsoft.AspNetCore.Hosting.Tests.csproj
+++ b/src/Hosting/Hosting/test/Microsoft.AspNetCore.Hosting.Tests.csproj
@@ -22,6 +22,7 @@
+
diff --git a/src/Http/Routing/test/UnitTests/Microsoft.AspNetCore.Routing.Tests.csproj b/src/Http/Routing/test/UnitTests/Microsoft.AspNetCore.Routing.Tests.csproj
index 39ae97878631..15a5702547b1 100644
--- a/src/Http/Routing/test/UnitTests/Microsoft.AspNetCore.Routing.Tests.csproj
+++ b/src/Http/Routing/test/UnitTests/Microsoft.AspNetCore.Routing.Tests.csproj
@@ -15,6 +15,7 @@
+
diff --git a/src/Http/Routing/test/UnitTests/RoutingMetricsTests.cs b/src/Http/Routing/test/UnitTests/RoutingMetricsTests.cs
index 6998afd595a0..e8338013317b 100644
--- a/src/Http/Routing/test/UnitTests/RoutingMetricsTests.cs
+++ b/src/Http/Routing/test/UnitTests/RoutingMetricsTests.cs
@@ -13,6 +13,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
using Moq;
namespace Microsoft.AspNetCore.Routing;
@@ -34,8 +35,8 @@ public async Task Match_Success()
var httpContext = new DefaultHttpContext();
var meter = meterFactory.Meters.Single();
- using var routingMatchSuccessRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
- using var routingMatchFailureRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
+ using var routingMatchSuccessCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
+ using var routingMatchFailureCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
// Act
await middleware.Invoke(httpContext);
@@ -44,9 +45,9 @@ public async Task Match_Success()
Assert.Equal(RoutingMetrics.MeterName, meter.Name);
Assert.Null(meter.Version);
- Assert.Collection(routingMatchSuccessRecorder.GetMeasurements(),
+ Assert.Collection(routingMatchSuccessCollector.GetMeasurementSnapshot(),
m => AssertSuccess(m, "/{hi}", fallback: false));
- Assert.Empty(routingMatchFailureRecorder.GetMeasurements());
+ Assert.Empty(routingMatchFailureCollector.GetMeasurementSnapshot());
}
[Theory]
@@ -70,8 +71,8 @@ public async Task Match_SuccessFallback_SetTagIfPresent(bool hasFallbackMetadata
var httpContext = new DefaultHttpContext();
var meter = meterFactory.Meters.Single();
- using var routingMatchSuccessRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
- using var routingMatchFailureRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
+ using var routingMatchSuccessCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
+ using var routingMatchFailureCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
// Act
await middleware.Invoke(httpContext);
@@ -80,9 +81,9 @@ public async Task Match_SuccessFallback_SetTagIfPresent(bool hasFallbackMetadata
Assert.Equal(RoutingMetrics.MeterName, meter.Name);
Assert.Null(meter.Version);
- Assert.Collection(routingMatchSuccessRecorder.GetMeasurements(),
+ Assert.Collection(routingMatchSuccessCollector.GetMeasurementSnapshot(),
m => AssertSuccess(m, "/{hi}", fallback: hasFallbackMetadata));
- Assert.Empty(routingMatchFailureRecorder.GetMeasurements());
+ Assert.Empty(routingMatchFailureCollector.GetMeasurementSnapshot());
}
[Fact]
@@ -99,8 +100,8 @@ public async Task Match_Success_MissingRoute()
var httpContext = new DefaultHttpContext();
var meter = meterFactory.Meters.Single();
- using var routingMatchSuccessRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
- using var routingMatchFailureRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
+ using var routingMatchSuccessCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
+ using var routingMatchFailureCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
// Act
await middleware.Invoke(httpContext);
@@ -109,9 +110,9 @@ public async Task Match_Success_MissingRoute()
Assert.Equal(RoutingMetrics.MeterName, meter.Name);
Assert.Null(meter.Version);
- Assert.Collection(routingMatchSuccessRecorder.GetMeasurements(),
+ Assert.Collection(routingMatchSuccessCollector.GetMeasurementSnapshot(),
m => AssertSuccess(m, "(missing)", fallback: false));
- Assert.Empty(routingMatchFailureRecorder.GetMeasurements());
+ Assert.Empty(routingMatchFailureCollector.GetMeasurementSnapshot());
}
[Fact]
@@ -125,8 +126,8 @@ public async Task Match_Failure()
var httpContext = new DefaultHttpContext();
var meter = meterFactory.Meters.Single();
- using var routingMatchSuccessRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
- using var routingMatchFailureRecorder = new InstrumentRecorder(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
+ using var routingMatchSuccessCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
+ using var routingMatchFailureCollector = new MetricCollector(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
// Act
await middleware.Invoke(httpContext);
@@ -135,16 +136,16 @@ public async Task Match_Failure()
Assert.Equal(RoutingMetrics.MeterName, meter.Name);
Assert.Null(meter.Version);
- Assert.Empty(routingMatchSuccessRecorder.GetMeasurements());
- Assert.Collection(routingMatchFailureRecorder.GetMeasurements(),
+ Assert.Empty(routingMatchSuccessCollector.GetMeasurementSnapshot());
+ Assert.Collection(routingMatchFailureCollector.GetMeasurementSnapshot(),
m => Assert.Equal(1, m.Value));
}
- private void AssertSuccess(Measurement measurement, string route, bool fallback)
+ private void AssertSuccess(CollectedMeasurement measurement, string route, bool fallback)
{
Assert.Equal(1, measurement.Value);
- Assert.Equal(route, (string)measurement.Tags.ToArray().Single(t => t.Key == "route").Value);
- Assert.Equal(fallback, (bool)measurement.Tags.ToArray().Single(t => t.Key == "fallback").Value);
+ Assert.Equal(route, (string)measurement.Tags["route"]);
+ Assert.Equal(fallback, (bool)measurement.Tags["fallback"]);
}
private EndpointRoutingMiddleware CreateMiddleware(
diff --git a/src/Middleware/Diagnostics/test/UnitTests/DeveloperExceptionPageMiddlewareTest.cs b/src/Middleware/Diagnostics/test/UnitTests/DeveloperExceptionPageMiddlewareTest.cs
index 435ccb394be2..5df91e9de41a 100644
--- a/src/Middleware/Diagnostics/test/UnitTests/DeveloperExceptionPageMiddlewareTest.cs
+++ b/src/Middleware/Diagnostics/test/UnitTests/DeveloperExceptionPageMiddlewareTest.cs
@@ -17,6 +17,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Metrics;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
namespace Microsoft.AspNetCore.Diagnostics;
@@ -538,16 +539,9 @@ public async Task NullInfoInCompilationException_ShouldNotThrowExceptionGenerati
public async Task UnhandledError_ExceptionNameTagAdded()
{
// Arrange
- var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
-
var meterFactory = new TestMeterFactory();
- using var requestDurationRecorder = new InstrumentRecorder(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
- using var requestExceptionRecorder = new InstrumentRecorder(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
- using var measurementReporter = new MeasurementReporter(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
- measurementReporter.Register(m =>
- {
- tcs.SetResult();
- });
+ using var requestDurationCollector = new MetricCollector(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
+ using var requestExceptionCollector = new MetricCollector(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
using var host = new HostBuilder()
.ConfigureServices(s =>
@@ -577,33 +571,33 @@ public async Task UnhandledError_ExceptionNameTagAdded()
var response = await server.CreateClient().GetAsync("/path");
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
- await tcs.Task.DefaultTimeout();
+ await requestDurationCollector.WaitForMeasurementsAsync(numMeasurements: 1).DefaultTimeout();
// Assert
Assert.Collection(
- requestDurationRecorder.GetMeasurements(),
+ requestDurationCollector.GetMeasurementSnapshot(),
m =>
{
Assert.True(m.Value > 0);
Assert.Equal(500, (int)m.Tags.ToArray().Single(t => t.Key == "status-code").Value);
Assert.Equal("System.Exception", (string)m.Tags.ToArray().Single(t => t.Key == "exception-name").Value);
});
- Assert.Collection(requestExceptionRecorder.GetMeasurements(),
+ Assert.Collection(requestExceptionCollector.GetMeasurementSnapshot(),
m => AssertRequestException(m, "System.Exception", "Unhandled"));
}
- private static void AssertRequestException(Measurement measurement, string exceptionName, string result, string handler = null)
+ private static void AssertRequestException(CollectedMeasurement measurement, string exceptionName, string result, string handler = null)
{
Assert.Equal(1, measurement.Value);
- Assert.Equal(exceptionName, (string)measurement.Tags.ToArray().Single(t => t.Key == "exception-name").Value);
- Assert.Equal(result, measurement.Tags.ToArray().Single(t => t.Key == "result").Value.ToString());
+ Assert.Equal(exceptionName, (string)measurement.Tags["exception-name"]);
+ Assert.Equal(result, measurement.Tags["result"].ToString());
if (handler == null)
{
- Assert.DoesNotContain(measurement.Tags.ToArray(), t => t.Key == "handler");
+ Assert.False(measurement.Tags.ContainsKey("handler"));
}
else
{
- Assert.Equal(handler, (string)measurement.Tags.ToArray().Single(t => t.Key == "handler").Value);
+ Assert.Equal(handler, (string)measurement.Tags["handler"]);
}
}
diff --git a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerMiddlewareTest.cs b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerMiddlewareTest.cs
index e6df4b587243..0a0b0fcf9c29 100644
--- a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerMiddlewareTest.cs
+++ b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerMiddlewareTest.cs
@@ -19,6 +19,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
using Moq;
namespace Microsoft.AspNetCore.Diagnostics;
@@ -210,7 +211,7 @@ public async Task Metrics_NoExceptionThrown()
var middleware = CreateMiddleware(_ => Task.CompletedTask, optionsAccessor, exceptionHandlers, meterFactory);
var meter = meterFactory.Meters.Single();
- using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
+ using var diagnosticsRequestExceptionCollector = new MetricCollector(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
// Act
await middleware.Invoke(httpContext);
@@ -219,7 +220,7 @@ public async Task Metrics_NoExceptionThrown()
Assert.Equal(DiagnosticsMetrics.MeterName, meter.Name);
Assert.Null(meter.Version);
- Assert.Empty(diagnosticsRequestExceptionRecorder.GetMeasurements());
+ Assert.Empty(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot());
}
[Fact]
@@ -233,13 +234,13 @@ public async Task Metrics_ExceptionThrown_Handled_Reported()
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, exceptionHandlers, meterFactory);
var meter = meterFactory.Meters.Single();
- using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
+ using var diagnosticsRequestExceptionCollector = new MetricCollector(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
// Act
await middleware.Invoke(httpContext);
// Assert
- Assert.Collection(diagnosticsRequestExceptionRecorder.GetMeasurements(),
+ Assert.Collection(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot(),
m => AssertRequestException(m, "System.InvalidOperationException", "Handled", typeof(TestExceptionHandler).FullName));
}
@@ -255,13 +256,13 @@ public async Task Metrics_ExceptionThrown_ResponseStarted_Skipped()
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, exceptionHandlers, meterFactory);
var meter = meterFactory.Meters.Single();
- using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
+ using var diagnosticsRequestExceptionCollector = new MetricCollector(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
// Act
await Assert.ThrowsAsync(() => middleware.Invoke(httpContext));
// Assert
- Assert.Collection(diagnosticsRequestExceptionRecorder.GetMeasurements(),
+ Assert.Collection(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot(),
m => AssertRequestException(m, "System.InvalidOperationException", "Skipped"));
}
@@ -280,13 +281,13 @@ public async Task Metrics_ExceptionThrown_DefaultSettings_Handled_Reported()
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, meterFactory: meterFactory);
var meter = meterFactory.Meters.Single();
- using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
+ using var diagnosticsRequestExceptionCollector = new MetricCollector(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
// Act
await middleware.Invoke(httpContext);
// Assert
- Assert.Collection(diagnosticsRequestExceptionRecorder.GetMeasurements(),
+ Assert.Collection(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot(),
m => AssertRequestException(m, "System.InvalidOperationException", "Handled", null));
}
@@ -304,28 +305,28 @@ public async Task Metrics_ExceptionThrown_Unhandled_Reported()
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, meterFactory: meterFactory);
var meter = meterFactory.Meters.Single();
- using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
+ using var diagnosticsRequestExceptionCollector = new MetricCollector(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
// Act
await Assert.ThrowsAsync(() => middleware.Invoke(httpContext));
// Assert
- Assert.Collection(diagnosticsRequestExceptionRecorder.GetMeasurements(),
+ Assert.Collection(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot(),
m => AssertRequestException(m, "System.InvalidOperationException", "Unhandled"));
}
- private static void AssertRequestException(Measurement measurement, string exceptionName, string result, string handler = null)
+ private static void AssertRequestException(CollectedMeasurement measurement, string exceptionName, string result, string handler = null)
{
Assert.Equal(1, measurement.Value);
- Assert.Equal(exceptionName, (string)measurement.Tags.ToArray().Single(t => t.Key == "exception-name").Value);
- Assert.Equal(result, measurement.Tags.ToArray().Single(t => t.Key == "result").Value.ToString());
+ Assert.Equal(exceptionName, (string)measurement.Tags["exception-name"]);
+ Assert.Equal(result, measurement.Tags["result"].ToString());
if (handler == null)
{
- Assert.DoesNotContain(measurement.Tags.ToArray(), t => t.Key == "handler");
+ Assert.False(measurement.Tags.ContainsKey("handler"));
}
else
{
- Assert.Equal(handler, (string)measurement.Tags.ToArray().Single(t => t.Key == "handler").Value);
+ Assert.Equal(handler, (string)measurement.Tags["handler"]);
}
}
diff --git a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs
index 13ec51b1903a..0d64d800dc1e 100644
--- a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs
+++ b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs
@@ -14,6 +14,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
namespace Microsoft.AspNetCore.Diagnostics;
@@ -915,15 +916,8 @@ public async Task ExceptionHandlerWithExceptionHandlerNotReplacedWithGlobalRoute
public async Task UnhandledError_ExceptionNameTagAdded()
{
// Arrange
- var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
-
var meterFactory = new TestMeterFactory();
- using var instrumentRecorder = new InstrumentRecorder(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
- using var measurementReporter = new MeasurementReporter(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
- measurementReporter.Register(m =>
- {
- tcs.SetResult();
- });
+ using var instrumentCollector = new MetricCollector(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
using var host = new HostBuilder()
.ConfigureServices(s =>
@@ -959,11 +953,11 @@ public async Task UnhandledError_ExceptionNameTagAdded()
var response = await server.CreateClient().GetAsync("/path");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
- await tcs.Task.DefaultTimeout();
+ await instrumentCollector.WaitForMeasurementsAsync(numMeasurements: 1).DefaultTimeout();
// Assert
Assert.Collection(
- instrumentRecorder.GetMeasurements(),
+ instrumentCollector.GetMeasurementSnapshot(),
m =>
{
Assert.True(m.Value > 0);
diff --git a/src/Middleware/Diagnostics/test/UnitTests/Microsoft.AspNetCore.Diagnostics.Tests.csproj b/src/Middleware/Diagnostics/test/UnitTests/Microsoft.AspNetCore.Diagnostics.Tests.csproj
index d01bdacc7058..6f2620a2e6ce 100644
--- a/src/Middleware/Diagnostics/test/UnitTests/Microsoft.AspNetCore.Diagnostics.Tests.csproj
+++ b/src/Middleware/Diagnostics/test/UnitTests/Microsoft.AspNetCore.Diagnostics.Tests.csproj
@@ -21,6 +21,7 @@
+
diff --git a/src/Middleware/RateLimiting/test/Microsoft.AspNetCore.RateLimiting.Tests.csproj b/src/Middleware/RateLimiting/test/Microsoft.AspNetCore.RateLimiting.Tests.csproj
index 7a307f93db64..56d83fee3271 100644
--- a/src/Middleware/RateLimiting/test/Microsoft.AspNetCore.RateLimiting.Tests.csproj
+++ b/src/Middleware/RateLimiting/test/Microsoft.AspNetCore.RateLimiting.Tests.csproj
@@ -8,6 +8,7 @@
+
diff --git a/src/Middleware/RateLimiting/test/RateLimitingMetricsTests.cs b/src/Middleware/RateLimiting/test/RateLimitingMetricsTests.cs
index 6ffd16e92a47..972f325afc11 100644
--- a/src/Middleware/RateLimiting/test/RateLimitingMetricsTests.cs
+++ b/src/Middleware/RateLimiting/test/RateLimitingMetricsTests.cs
@@ -14,6 +14,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
using Moq;
namespace Microsoft.AspNetCore.RateLimiting;
@@ -34,11 +35,11 @@ public async Task Metrics_Rejected()
var context = new DefaultHttpContext();
- using var leaseRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
- using var currentLeaseRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
- using var currentRequestsQueuedRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
- using var queuedRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
- using var leaseFailedRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
+ using var leaseRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
+ using var currentLeaseRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
+ using var currentRequestsQueuedCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
+ using var queuedRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
+ using var leaseFailedRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
// Act
await middleware.Invoke(context).DefaultTimeout();
@@ -46,11 +47,11 @@ public async Task Metrics_Rejected()
// Assert
Assert.Equal(StatusCodes.Status503ServiceUnavailable, context.Response.StatusCode);
- Assert.Empty(currentLeaseRequestsRecorder.GetMeasurements());
- Assert.Empty(leaseRequestDurationRecorder.GetMeasurements());
- Assert.Empty(currentRequestsQueuedRecorder.GetMeasurements());
- Assert.Empty(queuedRequestDurationRecorder.GetMeasurements());
- Assert.Collection(leaseFailedRequestsRecorder.GetMeasurements(),
+ Assert.Empty(currentLeaseRequestsCollector.GetMeasurementSnapshot());
+ Assert.Empty(leaseRequestDurationCollector.GetMeasurementSnapshot());
+ Assert.Empty(currentRequestsQueuedCollector.GetMeasurementSnapshot());
+ Assert.Empty(queuedRequestDurationCollector.GetMeasurementSnapshot());
+ Assert.Collection(leaseFailedRequestsCollector.GetMeasurementSnapshot(),
m =>
{
Assert.Equal(1, m.Value);
@@ -81,20 +82,20 @@ public async Task Metrics_Success()
var context = new DefaultHttpContext();
context.Request.Method = "GET";
- using var leaseRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
- using var currentLeaseRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
- using var currentRequestsQueuedRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
- using var queuedRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
- using var leaseFailedRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
+ using var leaseRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
+ using var currentLeaseRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
+ using var currentRequestsQueuedCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
+ using var queuedRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
+ using var leaseFailedRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
// Act
var middlewareTask = middleware.Invoke(context);
await syncPoint.WaitForSyncPoint().DefaultTimeout();
- Assert.Collection(currentLeaseRequestsRecorder.GetMeasurements(),
+ Assert.Collection(currentLeaseRequestsCollector.GetMeasurementSnapshot(),
m => AssertCounter(m, 1, null));
- Assert.Empty(leaseRequestDurationRecorder.GetMeasurements());
+ Assert.Empty(leaseRequestDurationCollector.GetMeasurementSnapshot());
syncPoint.Continue();
@@ -103,14 +104,14 @@ public async Task Metrics_Success()
// Assert
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
- Assert.Collection(currentLeaseRequestsRecorder.GetMeasurements(),
+ Assert.Collection(currentLeaseRequestsCollector.GetMeasurementSnapshot(),
m => AssertCounter(m, 1, null),
m => AssertCounter(m, -1, null));
- Assert.Collection(leaseRequestDurationRecorder.GetMeasurements(),
+ Assert.Collection(leaseRequestDurationCollector.GetMeasurementSnapshot(),
m => AssertDuration(m, null));
- Assert.Empty(currentRequestsQueuedRecorder.GetMeasurements());
- Assert.Empty(queuedRequestDurationRecorder.GetMeasurements());
- Assert.Empty(leaseFailedRequestsRecorder.GetMeasurements());
+ Assert.Empty(currentRequestsQueuedCollector.GetMeasurementSnapshot());
+ Assert.Empty(queuedRequestDurationCollector.GetMeasurementSnapshot());
+ Assert.Empty(leaseFailedRequestsCollector.GetMeasurementSnapshot());
}
[Fact]
@@ -141,11 +142,11 @@ public async Task Metrics_ListenInMiddleOfRequest_CurrentLeasesNotDecreased()
await syncPoint.WaitForSyncPoint().DefaultTimeout();
- using var leaseRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
- using var currentLeaseRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
- using var currentRequestsQueuedRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
- using var queuedRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
- using var leaseFailedRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
+ using var leaseRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
+ using var currentLeaseRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
+ using var currentRequestsQueuedCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
+ using var queuedRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
+ using var leaseFailedRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
syncPoint.Continue();
@@ -154,8 +155,8 @@ public async Task Metrics_ListenInMiddleOfRequest_CurrentLeasesNotDecreased()
// Assert
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
- Assert.Empty(currentLeaseRequestsRecorder.GetMeasurements());
- Assert.Collection(leaseRequestDurationRecorder.GetMeasurements(),
+ Assert.Empty(currentLeaseRequestsCollector.GetMeasurementSnapshot());
+ Assert.Collection(leaseRequestDurationCollector.GetMeasurementSnapshot(),
m => AssertDuration(m, null));
}
@@ -192,11 +193,11 @@ public async Task Metrics_Queued()
routeEndpointBuilder.Metadata.Add(new EnableRateLimitingAttribute("concurrencyPolicy"));
var endpoint = routeEndpointBuilder.Build();
- using var leaseRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
- using var currentLeaseRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
- using var currentRequestsQueuedRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
- using var queuedRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
- using var leaseFailedRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
+ using var leaseRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
+ using var currentLeaseRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
+ using var currentRequestsQueuedCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
+ using var queuedRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
+ using var leaseFailedRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
// Act
var context1 = new DefaultHttpContext();
@@ -213,9 +214,9 @@ public async Task Metrics_Queued()
var middlewareTask2 = middleware.Invoke(context1);
// Assert second request is queued.
- Assert.Collection(currentRequestsQueuedRecorder.GetMeasurements(),
+ Assert.Collection(currentRequestsQueuedCollector.GetMeasurementSnapshot(),
m => AssertCounter(m, 1, "concurrencyPolicy"));
- Assert.Empty(queuedRequestDurationRecorder.GetMeasurements());
+ Assert.Empty(queuedRequestDurationCollector.GetMeasurementSnapshot());
// Allow both requests to finish.
syncPoint.Continue();
@@ -223,10 +224,10 @@ public async Task Metrics_Queued()
await middlewareTask1.DefaultTimeout();
await middlewareTask2.DefaultTimeout();
- Assert.Collection(currentRequestsQueuedRecorder.GetMeasurements(),
+ Assert.Collection(currentRequestsQueuedCollector.GetMeasurementSnapshot(),
m => AssertCounter(m, 1, "concurrencyPolicy"),
m => AssertCounter(m, -1, "concurrencyPolicy"));
- Assert.Collection(queuedRequestDurationRecorder.GetMeasurements(),
+ Assert.Collection(queuedRequestDurationCollector.GetMeasurementSnapshot(),
m => AssertDuration(m, "concurrencyPolicy"));
}
@@ -279,14 +280,14 @@ public async Task Metrics_ListenInMiddleOfQueued_CurrentQueueNotDecreased()
// Start listening while the second request is queued.
- using var leaseRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
- using var currentLeaseRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
- using var currentRequestsQueuedRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
- using var queuedRequestDurationRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
- using var leaseFailedRequestsRecorder = new InstrumentRecorder(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
+ using var leaseRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
+ using var currentLeaseRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
+ using var currentRequestsQueuedCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
+ using var queuedRequestDurationCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
+ using var leaseFailedRequestsCollector = new MetricCollector(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
- Assert.Empty(currentRequestsQueuedRecorder.GetMeasurements());
- Assert.Empty(queuedRequestDurationRecorder.GetMeasurements());
+ Assert.Empty(currentRequestsQueuedCollector.GetMeasurementSnapshot());
+ Assert.Empty(queuedRequestDurationCollector.GetMeasurementSnapshot());
// Allow both requests to finish.
syncPoint.Continue();
@@ -294,24 +295,24 @@ public async Task Metrics_ListenInMiddleOfQueued_CurrentQueueNotDecreased()
await middlewareTask1.DefaultTimeout();
await middlewareTask2.DefaultTimeout();
- Assert.Empty(currentRequestsQueuedRecorder.GetMeasurements());
- Assert.Collection(queuedRequestDurationRecorder.GetMeasurements(),
+ Assert.Empty(currentRequestsQueuedCollector.GetMeasurementSnapshot());
+ Assert.Collection(queuedRequestDurationCollector.GetMeasurementSnapshot(),
m => AssertDuration(m, "concurrencyPolicy"));
}
- private static void AssertCounter(Measurement measurement, long value, string policy)
+ private static void AssertCounter(CollectedMeasurement measurement, long value, string policy)
{
Assert.Equal(value, measurement.Value);
AssertTag(measurement.Tags, "policy", policy);
}
- private static void AssertDuration(Measurement measurement, string policy)
+ private static void AssertDuration(CollectedMeasurement measurement, string policy)
{
Assert.True(measurement.Value > 0);
AssertTag(measurement.Tags, "policy", policy);
}
- private static void AssertTag(ReadOnlySpan> tags, string tagName, T expected)
+ private static void AssertTag(IReadOnlyDictionary tags, string tagName, T expected)
{
if (expected == null)
{
diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ConnectionLimitTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ConnectionLimitTests.cs
index 3eb165e19a7b..7f30315d4f66 100644
--- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ConnectionLimitTests.cs
+++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ConnectionLimitTests.cs
@@ -16,6 +16,7 @@
using Microsoft.AspNetCore.Server.Kestrel.Tests;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Diagnostics.Metrics;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests;
@@ -102,7 +103,7 @@ public async Task UpgradedConnectionsCountsAgainstDifferentLimit()
public async Task RejectsConnectionsWhenLimitReached()
{
var testMeterFactory = new TestMeterFactory();
- using var rejectedConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-rejected-connections");
+ using var rejectedConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-rejected-connections");
const int max = 10;
var requestTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -141,14 +142,14 @@ public async Task RejectsConnectionsWhenLimitReached()
}
var actions = Enumerable.Repeat(AssertCounter, i + 1).ToArray();
- Assert.Collection(rejectedConnections.GetMeasurements(), actions);
+ Assert.Collection(rejectedConnections.GetMeasurementSnapshot(), actions);
}
requestTcs.TrySetResult();
}
}
- static void AssertCounter(Measurement measurement) => Assert.Equal(1, measurement.Value);
+ static void AssertCounter(CollectedMeasurement measurement) => Assert.Equal(1, measurement.Value);
}
[Fact]
diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj b/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj
index 7f5ed843519d..e688c0c79bc8 100644
--- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj
+++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj
@@ -36,6 +36,7 @@
+
diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/KestrelMetricsTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/KestrelMetricsTests.cs
index 9945aa8be9ec..fafeb436fa38 100644
--- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/KestrelMetricsTests.cs
+++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/KestrelMetricsTests.cs
@@ -19,6 +19,7 @@
using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Diagnostics.Metrics;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests;
@@ -46,9 +47,9 @@ public async Task Http1Connection()
});
var testMeterFactory = new TestMeterFactory();
- using var connectionDuration = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- using var currentConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
- using var queuedConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
+ using var connectionDuration = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
+ using var currentConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
+ using var queuedConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
@@ -63,8 +64,8 @@ public async Task Http1Connection()
// Wait for connection to start on the server.
await sync.WaitForSyncPoint();
- Assert.Empty(connectionDuration.GetMeasurements());
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"));
+ Assert.Empty(connectionDuration.GetMeasurementSnapshot());
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"));
// Signal that connection can continue.
sync.Continue();
@@ -79,13 +80,13 @@ await connection.ReceiveEnd(
await connection.WaitForConnectionClose();
}
- Assert.Collection(connectionDuration.GetMeasurements(), m =>
+ Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m =>
{
AssertDuration(m, "127.0.0.1:0", "HTTP/1.1");
- Assert.Equal("value!", (string)m.Tags.ToArray().Single(t => t.Key == "custom").Value);
+ Assert.Equal("value!", (string)m.Tags["custom"]);
});
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
- Assert.Collection(queuedConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(queuedConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
}
[Fact]
@@ -122,9 +123,9 @@ public async Task Http1Connection_BeginListeningAfterConnectionStarted()
// Wait for connection to start on the server.
await sync.WaitForSyncPoint();
- using var connectionDuration = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- using var currentConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
- using var queuedConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
+ using var connectionDuration = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
+ using var currentConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
+ using var queuedConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
// Signal that connection can continue.
sync.Continue();
@@ -138,9 +139,9 @@ await connection.ReceiveEnd(
await connection.WaitForConnectionClose();
- Assert.Empty(connectionDuration.GetMeasurements());
- Assert.Empty(currentConnections.GetMeasurements());
- Assert.Empty(queuedConnections.GetMeasurements());
+ Assert.Empty(connectionDuration.GetMeasurementSnapshot());
+ Assert.Empty(currentConnections.GetMeasurementSnapshot());
+ Assert.Empty(queuedConnections.GetMeasurementSnapshot());
Assert.False(hasConnectionMetricsTagsFeature);
}
@@ -169,9 +170,9 @@ public async Task Http1Connection_IHttpConnectionTagsFeatureIgnoreFeatureSetOnTr
});
var testMeterFactory = new TestMeterFactory();
- using var connectionDuration = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- using var currentConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
- using var queuedConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
+ using var connectionDuration = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
+ using var currentConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
+ using var queuedConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
@@ -195,8 +196,8 @@ public async Task Http1Connection_IHttpConnectionTagsFeatureIgnoreFeatureSetOnTr
Assert.NotEqual(overridenFeature, currentConnectionContext.Features.Get());
- Assert.Empty(connectionDuration.GetMeasurements());
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"));
+ Assert.Empty(connectionDuration.GetMeasurementSnapshot());
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"));
// Signal that connection can continue.
sync.Continue();
@@ -211,14 +212,14 @@ await connection.ReceiveEnd(
await connection.WaitForConnectionClose();
}
- Assert.Collection(connectionDuration.GetMeasurements(), m =>
+ Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m =>
{
AssertDuration(m, "127.0.0.1:0", "HTTP/1.1");
- Assert.Equal("value!", (string)m.Tags.ToArray().Single(t => t.Key == "custom").Value);
- Assert.Empty(m.Tags.ToArray().Where(t => t.Key == "test"));
+ Assert.Equal("value!", (string)m.Tags["custom"]);
+ Assert.False(m.Tags.ContainsKey("test"));
});
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
- Assert.Collection(queuedConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(queuedConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
}
private sealed class TestConnectionMetricsTagsFeature : IConnectionMetricsTagsFeature
@@ -244,9 +245,9 @@ public async Task Http1Connection_Error()
});
var testMeterFactory = new TestMeterFactory();
- using var connectionDuration = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- using var currentConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
- using var queuedConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
+ using var connectionDuration = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
+ using var currentConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
+ using var queuedConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
@@ -261,8 +262,8 @@ public async Task Http1Connection_Error()
// Wait for connection to start on the server.
await sync.WaitForSyncPoint();
- Assert.Empty(connectionDuration.GetMeasurements());
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"));
+ Assert.Empty(connectionDuration.GetMeasurementSnapshot());
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"));
// Signal that connection can continue.
sync.Continue();
@@ -272,13 +273,13 @@ public async Task Http1Connection_Error()
await connection.WaitForConnectionClose();
}
- Assert.Collection(connectionDuration.GetMeasurements(), m =>
+ Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m =>
{
AssertDuration(m, "127.0.0.1:0", httpProtocol: null);
- Assert.Equal("System.InvalidOperationException", (string)m.Tags.ToArray().Single(t => t.Key == "exception-name").Value);
+ Assert.Equal("System.InvalidOperationException", (string)m.Tags["exception-name"]);
});
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
- Assert.Collection(queuedConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(queuedConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
}
[Fact]
@@ -287,9 +288,9 @@ public async Task Http1Connection_Upgrade()
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
var testMeterFactory = new TestMeterFactory();
- using var connectionDuration = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- using var currentConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
- using var currentUpgradedRequests = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-upgraded-connections");
+ using var connectionDuration = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
+ using var currentConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
+ using var currentUpgradedRequests = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-upgraded-connections");
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
@@ -305,9 +306,9 @@ await connection.ReceiveEnd("HTTP/1.1 101 Switching Protocols",
"");
}
- Assert.Collection(connectionDuration.GetMeasurements(), m => AssertDuration(m, "127.0.0.1:0", "HTTP/1.1"));
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
- Assert.Collection(currentUpgradedRequests.GetMeasurements(), m => Assert.Equal(1, m.Value), m => Assert.Equal(-1, m.Value));
+ Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m => AssertDuration(m, "127.0.0.1:0", "HTTP/1.1"));
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(currentUpgradedRequests.GetMeasurementSnapshot(), m => Assert.Equal(1, m.Value), m => Assert.Equal(-1, m.Value));
static async Task UpgradeApp(HttpContext context)
{
@@ -331,12 +332,12 @@ public async Task Http2Connection()
var requestsReceived = 0;
var testMeterFactory = new TestMeterFactory();
- using var connectionDuration = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- using var currentConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
- using var queuedConnections = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
- using var queuedRequests = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-requests");
- using var tlsHandshakeDuration = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-tls-handshake-duration");
- using var currentTlsHandshakes = new InstrumentRecorder(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-tls-handshakes");
+ using var connectionDuration = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
+ using var currentConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
+ using var queuedConnections = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
+ using var queuedRequests = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-requests");
+ using var tlsHandshakeDuration = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-tls-handshake-duration");
+ using var currentTlsHandshakes = new MetricCollector(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-tls-handshakes");
await using (var server = new TestServer(context =>
{
@@ -393,27 +394,27 @@ public async Task Http2Connection()
Assert.NotNull(connectionId);
Assert.Equal(2, requestsReceived);
- Assert.Collection(connectionDuration.GetMeasurements(), m => AssertDuration(m, "127.0.0.1:0", "HTTP/2"));
- Assert.Collection(currentConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
- Assert.Collection(queuedConnections.GetMeasurements(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m => AssertDuration(m, "127.0.0.1:0", "HTTP/2"));
+ Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
+ Assert.Collection(queuedConnections.GetMeasurementSnapshot(), m => AssertCount(m, 1, "127.0.0.1:0"), m => AssertCount(m, -1, "127.0.0.1:0"));
- Assert.Collection(queuedRequests.GetMeasurements(),
+ Assert.Collection(queuedRequests.GetMeasurementSnapshot(),
m => AssertRequestCount(m, 1, "HTTP/2"),
m => AssertRequestCount(m, -1, "HTTP/2"),
m => AssertRequestCount(m, 1, "HTTP/2"),
m => AssertRequestCount(m, -1, "HTTP/2"));
- Assert.Collection(tlsHandshakeDuration.GetMeasurements(), m =>
+ Assert.Collection(tlsHandshakeDuration.GetMeasurementSnapshot(), m =>
{
Assert.True(m.Value > 0);
- Assert.Equal("Tls12", (string)m.Tags.ToArray().Single(t => t.Key == "protocol").Value);
+ Assert.Equal("Tls12", (string)m.Tags["protocol"]);
});
- Assert.Collection(currentTlsHandshakes.GetMeasurements(), m => Assert.Equal(1, m.Value), m => Assert.Equal(-1, m.Value));
+ Assert.Collection(currentTlsHandshakes.GetMeasurementSnapshot(), m => Assert.Equal(1, m.Value), m => Assert.Equal(-1, m.Value));
- static void AssertRequestCount(Measurement measurement, long expectedValue, string httpVersion)
+ static void AssertRequestCount(CollectedMeasurement measurement, long expectedValue, string httpVersion)
{
Assert.Equal(expectedValue, measurement.Value);
- Assert.Equal(httpVersion, (string)measurement.Tags.ToArray().Single(t => t.Key == "version").Value);
+ Assert.Equal(httpVersion, (string)measurement.Tags["version"]);
}
}
@@ -430,23 +431,23 @@ private static async Task EchoApp(HttpContext httpContext)
}
}
- private static void AssertDuration(Measurement measurement, string localEndpoint, string httpProtocol)
+ private static void AssertDuration(CollectedMeasurement measurement, string localEndpoint, string httpProtocol)
{
Assert.True(measurement.Value > 0);
- Assert.Equal(localEndpoint, (string)measurement.Tags.ToArray().Single(t => t.Key == "endpoint").Value);
+ Assert.Equal(localEndpoint, (string)measurement.Tags["endpoint"]);
if (httpProtocol is not null)
{
- Assert.Equal(httpProtocol, (string)measurement.Tags.ToArray().Single(t => t.Key == "http-protocol").Value);
+ Assert.Equal(httpProtocol, (string)measurement.Tags["http-protocol"]);
}
else
{
- Assert.DoesNotContain(measurement.Tags.ToArray(), t => t.Key == "http-protocol");
+ Assert.False(measurement.Tags.ContainsKey("http-protocol"));
}
}
- private static void AssertCount(Measurement measurement, long expectedValue, string localEndpoint)
+ private static void AssertCount(CollectedMeasurement measurement, long expectedValue, string localEndpoint)
{
Assert.Equal(expectedValue, measurement.Value);
- Assert.Equal(localEndpoint, (string)measurement.Tags.ToArray().Single(t => t.Key == "endpoint").Value);
+ Assert.Equal(localEndpoint, (string)measurement.Tags["endpoint"]);
}
}
diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs
index 74fefad7a6ca..a2b9564bec8d 100644
--- a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs
+++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http2/Http2RequestTests.cs
@@ -16,6 +16,7 @@
using Microsoft.Extensions.Diagnostics.Metrics;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
namespace Interop.FunctionalTests.Http2;
@@ -37,13 +38,7 @@ public async Task GET_Metrics_HttpProtocolAndTlsSet()
{
var meterFactory = host.Services.GetRequiredService();
- var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- using var connectionDuration = new InstrumentRecorder(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- using var measurementReporter = new MeasurementReporter(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
- measurementReporter.Register(m =>
- {
- tcs.SetResult();
- });
+ using var connectionDuration = new MetricCollector(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
await host.StartAsync();
var client = HttpHelpers.CreateClient();
@@ -61,16 +56,16 @@ public async Task GET_Metrics_HttpProtocolAndTlsSet()
// Dispose the client to end the connection.
client.Dispose();
// Wait for measurement to be available.
- await tcs.Task.DefaultTimeout();
+ await connectionDuration.WaitForMeasurementsAsync(numMeasurements: 1).DefaultTimeout();
// Assert
- Assert.Collection(connectionDuration.GetMeasurements(),
+ Assert.Collection(connectionDuration.GetMeasurementSnapshot(),
m =>
{
Assert.True(m.Value > 0);
- Assert.Equal(protocol.ToString(), m.Tags.ToArray().Single(t => t.Key == "tls-protocol").Value);
- Assert.Equal("HTTP/2", m.Tags.ToArray().Single(t => t.Key == "http-protocol").Value);
- Assert.Equal($"127.0.0.1:{host.GetPort()}", m.Tags.ToArray().Single(t => t.Key == "endpoint").Value);
+ Assert.Equal(protocol.ToString(), m.Tags["tls-protocol"]);
+ Assert.Equal("HTTP/2", m.Tags["http-protocol"]);
+ Assert.Equal($"127.0.0.1:{host.GetPort()}", m.Tags["endpoint"]);
});
await host.StopAsync();
diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs
index 327e0a1cc19c..a81496c5dd43 100644
--- a/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs
+++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3RequestTests.cs
@@ -24,6 +24,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
using Microsoft.Extensions.Primitives;
+using Microsoft.Extensions.Telemetry.Testing.Metering;
using Xunit;
namespace Interop.FunctionalTests.Http3;
@@ -81,13 +82,7 @@ public async Task GET_Metrics_HttpProtocolAndTlsSet()
{
var meterFactory = host.Services.GetRequiredService