зеркало из https://github.com/dotnet/aspnetcore.git
Replace InstrumentRecorder with MetricCollector (#48931)
This commit is contained in:
Родитель
0356ba0fc4
Коммит
03edc26ae2
|
@ -62,6 +62,7 @@ and are generated based on the last package release.
|
|||
<LatestPackageReference Include="Microsoft.Extensions.Options.DataAnnotations" />
|
||||
<LatestPackageReference Include="Microsoft.Extensions.Options" />
|
||||
<LatestPackageReference Include="Microsoft.Extensions.Primitives" />
|
||||
<LatestPackageReference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
<LatestPackageReference Include="Microsoft.Win32.Registry" />
|
||||
<LatestPackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" />
|
||||
<LatestPackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" />
|
||||
|
|
|
@ -385,6 +385,10 @@
|
|||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>e2334b2be36919347923d0ec872a46acddb1e385</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Telemetry.Testing" Version="8.0.0-preview.6.23320.3">
|
||||
<Uri>https://github.com/dotnet/extensions</Uri>
|
||||
<Sha>a0e9c8794e3e0ba27033a9f54a545385228d0876</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="NuGet.Frameworks" Version="6.2.4">
|
||||
<Uri>https://github.com/nuget/nuget.client</Uri>
|
||||
<Sha>8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8</Sha>
|
||||
|
|
|
@ -134,6 +134,8 @@
|
|||
<SystemDiagnosticsPerformanceCounterVersion>8.0.0-preview.6.23318.9</SystemDiagnosticsPerformanceCounterVersion>
|
||||
<SystemIOHashingVersion>8.0.0-preview.6.23318.9</SystemIOHashingVersion>
|
||||
<SystemRuntimeCachingVersion>8.0.0-preview.6.23318.9</SystemRuntimeCachingVersion>
|
||||
<!-- Packages from dotnet/extensions -->
|
||||
<MicrosoftExtensionsTelemetryTestingVersion>8.0.0-preview.6.23320.3</MicrosoftExtensionsTelemetryTestingVersion>
|
||||
<!-- Packages from dotnet/efcore -->
|
||||
<dotnetefVersion>8.0.0-preview.6.23319.5</dotnetefVersion>
|
||||
<MicrosoftEntityFrameworkCoreInMemoryVersion>8.0.0-preview.6.23319.5</MicrosoftEntityFrameworkCoreInMemoryVersion>
|
||||
|
|
|
@ -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.AspNetCore.Testing;
|
|||
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 class HostingApplicationDiagnosticsTests
|
|||
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<long>(testMeterFactory1, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var currentRequestsRecorder2 = new InstrumentRecorder<long>(testMeterFactory2, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var requestDurationRecorder1 = new InstrumentRecorder<double>(testMeterFactory1, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var requestDurationRecorder2 = new InstrumentRecorder<double>(testMeterFactory2, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var currentRequestsRecorder1 = new MetricCollector<long>(testMeterFactory1, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var currentRequestsRecorder2 = new MetricCollector<long>(testMeterFactory2, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var requestDurationRecorder1 = new MetricCollector<double>(testMeterFactory1, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var requestDurationRecorder2 = new MetricCollector<double>(testMeterFactory2, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
|
||||
// Act/Assert 1
|
||||
var context1 = hostingApplication1.CreateContext(features1);
|
||||
|
@ -74,15 +74,15 @@ public class HostingApplicationDiagnosticsTests
|
|||
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 class HostingApplicationDiagnosticsTests
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Testing;
|
|||
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 class HostingMetricsTests
|
|||
var httpContext = new DefaultHttpContext();
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var requestDurationRecorder = new InstrumentRecorder<double>(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var currentRequestsRecorder = new InstrumentRecorder<long>(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var unhandledRequestsRecorder = new InstrumentRecorder<long>(meterFactory, HostingMetrics.MeterName, "http-server-unhandled-requests");
|
||||
using var requestDurationCollector = new MetricCollector<double>(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var currentRequestsCollector = new MetricCollector<long>(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var unhandledRequestsCollector = new MetricCollector<long>(meterFactory, HostingMetrics.MeterName, "http-server-unhandled-requests");
|
||||
|
||||
// Act/Assert
|
||||
Assert.Equal(HostingMetrics.MeterName, meter.Name);
|
||||
|
@ -39,10 +40,10 @@ public class HostingMetricsTests
|
|||
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 class HostingMetricsTests
|
|||
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 class HostingMetricsTests
|
|||
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<double> measurement, string protocol, int statusCode, string exceptionName = null)
|
||||
static void AssertRequestDuration(CollectedMeasurement<double> 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 class HostingMetricsTests
|
|||
|
||||
await syncPoint.WaitForSyncPoint().DefaultTimeout();
|
||||
|
||||
using var requestDurationRecorder = new InstrumentRecorder<double>(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var currentRequestsRecorder = new InstrumentRecorder<long>(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var requestDurationCollector = new MetricCollector<double>(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var currentRequestsCollector = new MetricCollector<long>(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
context1.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
|
||||
|
||||
syncPoint.Continue();
|
||||
|
@ -141,8 +142,8 @@ public class HostingMetricsTests
|
|||
|
||||
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 class HostingMetricsTests
|
|||
var httpContext = new DefaultHttpContext();
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var requestDurationRecorder = new InstrumentRecorder<double>(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var currentRequestsRecorder = new InstrumentRecorder<long>(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
using var requestDurationCollector = new MetricCollector<double>(meterFactory, HostingMetrics.MeterName, "http-server-request-duration");
|
||||
using var currentRequestsCollector = new MetricCollector<long>(meterFactory, HostingMetrics.MeterName, "http-server-current-requests");
|
||||
|
||||
// Act/Assert
|
||||
Assert.Equal(HostingMetrics.MeterName, meter.Name);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||
<Reference Include="Microsoft.Extensions.Hosting" />
|
||||
<Reference Include="Microsoft.Extensions.Options" />
|
||||
<Reference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
<Reference Include="System.Threading.Channels" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<Reference Include="Microsoft.Extensions.Diagnostics" />
|
||||
<Reference Include="Microsoft.Extensions.Hosting.Abstractions" />
|
||||
<Reference Include="Microsoft.Extensions.Logging" />
|
||||
<Reference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
<Reference Include="Microsoft.Extensions.WebEncoders" />
|
||||
|
||||
<Compile Include="$(SharedSourceRoot)Metrics\TestMeterFactory.cs" LinkBase="shared" />
|
||||
|
|
|
@ -13,6 +13,7 @@ using Microsoft.Extensions.Diagnostics.Metrics;
|
|||
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 class RoutingMetricsTests
|
|||
var httpContext = new DefaultHttpContext();
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var routingMatchSuccessRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
using var routingMatchSuccessCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
|
@ -44,9 +45,9 @@ public class RoutingMetricsTests
|
|||
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 class RoutingMetricsTests
|
|||
var httpContext = new DefaultHttpContext();
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var routingMatchSuccessRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
using var routingMatchSuccessCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
|
@ -80,9 +81,9 @@ public class RoutingMetricsTests
|
|||
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 class RoutingMetricsTests
|
|||
var httpContext = new DefaultHttpContext();
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var routingMatchSuccessRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
using var routingMatchSuccessCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
|
@ -109,9 +110,9 @@ public class RoutingMetricsTests
|
|||
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 class RoutingMetricsTests
|
|||
var httpContext = new DefaultHttpContext();
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var routingMatchSuccessRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureRecorder = new InstrumentRecorder<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
using var routingMatchSuccessCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-success");
|
||||
using var routingMatchFailureCollector = new MetricCollector<long>(meterFactory, RoutingMetrics.MeterName, "routing-match-failure");
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
|
@ -135,16 +136,16 @@ public class RoutingMetricsTests
|
|||
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<long> measurement, string route, bool fallback)
|
||||
private void AssertSuccess(CollectedMeasurement<long> 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(
|
||||
|
|
|
@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Testing;
|
|||
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 class DeveloperExceptionPageMiddlewareTest : LoggedTest
|
|||
public async Task UnhandledError_ExceptionNameTagAdded()
|
||||
{
|
||||
// Arrange
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var meterFactory = new TestMeterFactory();
|
||||
using var requestDurationRecorder = new InstrumentRecorder<double>(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
|
||||
using var requestExceptionRecorder = new InstrumentRecorder<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
using var measurementReporter = new MeasurementReporter<double>(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
|
||||
measurementReporter.Register(m =>
|
||||
{
|
||||
tcs.SetResult();
|
||||
});
|
||||
using var requestDurationCollector = new MetricCollector<double>(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
|
||||
using var requestExceptionCollector = new MetricCollector<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
|
||||
using var host = new HostBuilder()
|
||||
.ConfigureServices(s =>
|
||||
|
@ -577,33 +571,33 @@ public class DeveloperExceptionPageMiddlewareTest : LoggedTest
|
|||
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<long> measurement, string exceptionName, string result, string handler = null)
|
||||
private static void AssertRequestException(CollectedMeasurement<long> 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"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ using Microsoft.Extensions.Diagnostics.Metrics;
|
|||
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 class ExceptionHandlerMiddlewareTest
|
|||
var middleware = CreateMiddleware(_ => Task.CompletedTask, optionsAccessor, exceptionHandlers, meterFactory);
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
using var diagnosticsRequestExceptionCollector = new MetricCollector<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
|
@ -219,7 +220,7 @@ public class ExceptionHandlerMiddlewareTest
|
|||
Assert.Equal(DiagnosticsMetrics.MeterName, meter.Name);
|
||||
Assert.Null(meter.Version);
|
||||
|
||||
Assert.Empty(diagnosticsRequestExceptionRecorder.GetMeasurements());
|
||||
Assert.Empty(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -233,13 +234,13 @@ public class ExceptionHandlerMiddlewareTest
|
|||
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, exceptionHandlers, meterFactory);
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
using var diagnosticsRequestExceptionCollector = new MetricCollector<long>(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 class ExceptionHandlerMiddlewareTest
|
|||
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, exceptionHandlers, meterFactory);
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
using var diagnosticsRequestExceptionCollector = new MetricCollector<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
|
||||
// Act
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => middleware.Invoke(httpContext));
|
||||
|
||||
// Assert
|
||||
Assert.Collection(diagnosticsRequestExceptionRecorder.GetMeasurements(),
|
||||
Assert.Collection(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot(),
|
||||
m => AssertRequestException(m, "System.InvalidOperationException", "Skipped"));
|
||||
}
|
||||
|
||||
|
@ -280,13 +281,13 @@ public class ExceptionHandlerMiddlewareTest
|
|||
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, meterFactory: meterFactory);
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
using var diagnosticsRequestExceptionCollector = new MetricCollector<long>(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 class ExceptionHandlerMiddlewareTest
|
|||
var middleware = CreateMiddleware(_ => throw new InvalidOperationException(), optionsAccessor, meterFactory: meterFactory);
|
||||
var meter = meterFactory.Meters.Single();
|
||||
|
||||
using var diagnosticsRequestExceptionRecorder = new InstrumentRecorder<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
using var diagnosticsRequestExceptionCollector = new MetricCollector<long>(meterFactory, DiagnosticsMetrics.MeterName, "diagnostics-handler-exception");
|
||||
|
||||
// Act
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => middleware.Invoke(httpContext));
|
||||
|
||||
// Assert
|
||||
Assert.Collection(diagnosticsRequestExceptionRecorder.GetMeasurements(),
|
||||
Assert.Collection(diagnosticsRequestExceptionCollector.GetMeasurementSnapshot(),
|
||||
m => AssertRequestException(m, "System.InvalidOperationException", "Unhandled"));
|
||||
}
|
||||
|
||||
private static void AssertRequestException(Measurement<long> measurement, string exceptionName, string result, string handler = null)
|
||||
private static void AssertRequestException(CollectedMeasurement<long> 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"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ using Microsoft.Extensions.Diagnostics.Metrics;
|
|||
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 class ExceptionHandlerTest
|
|||
public async Task UnhandledError_ExceptionNameTagAdded()
|
||||
{
|
||||
// Arrange
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var meterFactory = new TestMeterFactory();
|
||||
using var instrumentRecorder = new InstrumentRecorder<double>(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
|
||||
using var measurementReporter = new MeasurementReporter<double>(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
|
||||
measurementReporter.Register(m =>
|
||||
{
|
||||
tcs.SetResult();
|
||||
});
|
||||
using var instrumentCollector = new MetricCollector<double>(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
|
||||
|
||||
using var host = new HostBuilder()
|
||||
.ConfigureServices(s =>
|
||||
|
@ -959,11 +953,11 @@ public class ExceptionHandlerTest
|
|||
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);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<Reference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<Reference Include="Microsoft.Extensions.DiagnosticAdapter" />
|
||||
<Reference Include="Microsoft.Extensions.FileProviders.Embedded" />
|
||||
<Reference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
<Reference Include="Microsoft.AspNetCore" />
|
||||
<Reference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<Reference Include="Microsoft.AspNetCore.Http" />
|
||||
<Reference Include="Microsoft.AspNetCore.RateLimiting" />
|
||||
<Reference Include="Microsoft.AspNetCore.Routing" />
|
||||
<Reference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
|
||||
<Compile Include="$(SharedSourceRoot)Metrics\TestMeterFactory.cs" LinkBase="shared" />
|
||||
<Compile Include="$(SharedSourceRoot)SyncPoint\SyncPoint.cs" LinkBase="shared" />
|
||||
|
|
|
@ -14,6 +14,7 @@ using Microsoft.Extensions.Diagnostics.Metrics;
|
|||
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 class RateLimitingMetricsTests
|
|||
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
using var leaseRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
using var leaseRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context).DefaultTimeout();
|
||||
|
@ -46,11 +47,11 @@ public class RateLimitingMetricsTests
|
|||
// 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 class RateLimitingMetricsTests
|
|||
var context = new DefaultHttpContext();
|
||||
context.Request.Method = "GET";
|
||||
|
||||
using var leaseRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
using var leaseRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsCollector = new MetricCollector<long>(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 class RateLimitingMetricsTests
|
|||
// 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 class RateLimitingMetricsTests
|
|||
|
||||
await syncPoint.WaitForSyncPoint().DefaultTimeout();
|
||||
|
||||
using var leaseRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
using var leaseRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
|
||||
syncPoint.Continue();
|
||||
|
||||
|
@ -154,8 +155,8 @@ public class RateLimitingMetricsTests
|
|||
// 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 class RateLimitingMetricsTests
|
|||
routeEndpointBuilder.Metadata.Add(new EnableRateLimitingAttribute("concurrencyPolicy"));
|
||||
var endpoint = routeEndpointBuilder.Build();
|
||||
|
||||
using var leaseRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
using var leaseRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
|
||||
// Act
|
||||
var context1 = new DefaultHttpContext();
|
||||
|
@ -213,9 +214,9 @@ public class RateLimitingMetricsTests
|
|||
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 class RateLimitingMetricsTests
|
|||
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 class RateLimitingMetricsTests
|
|||
|
||||
// Start listening while the second request is queued.
|
||||
|
||||
using var leaseRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationRecorder = new InstrumentRecorder<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsRecorder = new InstrumentRecorder<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-lease-failed-requests");
|
||||
using var leaseRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-leased-request-duration");
|
||||
using var currentLeaseRequestsCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-leased-requests");
|
||||
using var currentRequestsQueuedCollector = new MetricCollector<long>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-current-queued-requests");
|
||||
using var queuedRequestDurationCollector = new MetricCollector<double>(meterFactory, RateLimitingMetrics.MeterName, "rate-limiting-queued-request-duration");
|
||||
using var leaseFailedRequestsCollector = new MetricCollector<long>(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 class RateLimitingMetricsTests
|
|||
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<long> measurement, long value, string policy)
|
||||
private static void AssertCounter(CollectedMeasurement<long> measurement, long value, string policy)
|
||||
{
|
||||
Assert.Equal(value, measurement.Value);
|
||||
AssertTag(measurement.Tags, "policy", policy);
|
||||
}
|
||||
|
||||
private static void AssertDuration(Measurement<double> measurement, string policy)
|
||||
private static void AssertDuration(CollectedMeasurement<double> measurement, string policy)
|
||||
{
|
||||
Assert.True(measurement.Value > 0);
|
||||
AssertTag(measurement.Tags, "policy", policy);
|
||||
}
|
||||
|
||||
private static void AssertTag<T>(ReadOnlySpan<KeyValuePair<string, object>> tags, string tagName, T expected)
|
||||
private static void AssertTag<T>(IReadOnlyDictionary<string, object> tags, string tagName, T expected)
|
||||
{
|
||||
if (expected == null)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport
|
|||
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 class ConnectionLimitTests : LoggedTest
|
|||
public async Task RejectsConnectionsWhenLimitReached()
|
||||
{
|
||||
var testMeterFactory = new TestMeterFactory();
|
||||
using var rejectedConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-rejected-connections");
|
||||
using var rejectedConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-rejected-connections");
|
||||
|
||||
const int max = 10;
|
||||
var requestTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
@ -141,14 +142,14 @@ public class ConnectionLimitTests : LoggedTest
|
|||
}
|
||||
|
||||
var actions = Enumerable.Repeat(AssertCounter, i + 1).ToArray();
|
||||
Assert.Collection(rejectedConnections.GetMeasurements(), actions);
|
||||
Assert.Collection(rejectedConnections.GetMeasurementSnapshot(), actions);
|
||||
}
|
||||
|
||||
requestTcs.TrySetResult();
|
||||
}
|
||||
}
|
||||
|
||||
static void AssertCounter(Measurement<long> measurement) => Assert.Equal(1, measurement.Value);
|
||||
static void AssertCounter(CollectedMeasurement<long> measurement) => Assert.Equal(1, measurement.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<Reference Include="System.Threading.Channels" />
|
||||
<Reference Include="Microsoft.AspNetCore.Http.Abstractions" />
|
||||
<Reference Include="Microsoft.AspNetCore.Server.Kestrel" />
|
||||
<Reference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
<Reference Include="Newtonsoft.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
|||
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 class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
});
|
||||
|
||||
var testMeterFactory = new TestMeterFactory();
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
|
||||
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
|
||||
|
||||
|
@ -63,8 +64,8 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
// 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 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
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 class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
// Wait for connection to start on the server.
|
||||
await sync.WaitForSyncPoint();
|
||||
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
|
||||
// Signal that connection can continue.
|
||||
sync.Continue();
|
||||
|
@ -138,9 +139,9 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
|
||||
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 class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
});
|
||||
|
||||
var testMeterFactory = new TestMeterFactory();
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
|
||||
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
|
||||
|
||||
|
@ -195,8 +196,8 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
|
||||
Assert.NotEqual(overridenFeature, currentConnectionContext.Features.Get<IConnectionMetricsTagsFeature>());
|
||||
|
||||
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 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
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 class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
});
|
||||
|
||||
var testMeterFactory = new TestMeterFactory();
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
|
||||
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
|
||||
|
||||
|
@ -261,8 +262,8 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
// 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 class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
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 class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
|
||||
|
||||
var testMeterFactory = new TestMeterFactory();
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var currentUpgradedRequests = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-upgraded-connections");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var currentUpgradedRequests = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-upgraded-connections");
|
||||
|
||||
var serviceContext = new TestServiceContext(LoggerFactory, metrics: new KestrelMetrics(testMeterFactory));
|
||||
|
||||
|
@ -305,9 +306,9 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
"");
|
||||
}
|
||||
|
||||
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 class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
var requestsReceived = 0;
|
||||
|
||||
var testMeterFactory = new TestMeterFactory();
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
using var queuedRequests = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-requests");
|
||||
using var tlsHandshakeDuration = new InstrumentRecorder<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-tls-handshake-duration");
|
||||
using var currentTlsHandshakes = new InstrumentRecorder<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-tls-handshakes");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-connections");
|
||||
using var queuedConnections = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-connections");
|
||||
using var queuedRequests = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-queued-requests");
|
||||
using var tlsHandshakeDuration = new MetricCollector<double>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-tls-handshake-duration");
|
||||
using var currentTlsHandshakes = new MetricCollector<long>(testMeterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-current-tls-handshakes");
|
||||
|
||||
await using (var server = new TestServer(context =>
|
||||
{
|
||||
|
@ -393,27 +394,27 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
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<long> measurement, long expectedValue, string httpVersion)
|
||||
static void AssertRequestCount(CollectedMeasurement<long> 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 @@ public class KestrelMetricsTests : TestApplicationErrorLoggerLoggedTest
|
|||
}
|
||||
}
|
||||
|
||||
private static void AssertDuration(Measurement<double> measurement, string localEndpoint, string httpProtocol)
|
||||
private static void AssertDuration(CollectedMeasurement<double> 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<long> measurement, long expectedValue, string localEndpoint)
|
||||
private static void AssertCount(CollectedMeasurement<long> 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"]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
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 class Http2RequestTests : LoggedTest
|
|||
{
|
||||
var meterFactory = host.Services.GetRequiredService<IMeterFactory>();
|
||||
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using var connectionDuration = new InstrumentRecorder<double>(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var measurementReporter = new MeasurementReporter<double>(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
measurementReporter.Register(m =>
|
||||
{
|
||||
tcs.SetResult();
|
||||
});
|
||||
using var connectionDuration = new MetricCollector<double>(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
|
||||
await host.StartAsync();
|
||||
var client = HttpHelpers.CreateClient();
|
||||
|
@ -61,16 +56,16 @@ public class Http2RequestTests : LoggedTest
|
|||
// 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();
|
||||
|
|
|
@ -24,6 +24,7 @@ using Microsoft.Extensions.Hosting;
|
|||
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 class Http3RequestTests : LoggedTest
|
|||
{
|
||||
var meterFactory = host.Services.GetRequiredService<IMeterFactory>();
|
||||
|
||||
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using var connectionDuration = new InstrumentRecorder<double>(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
using var measurementReporter = new MeasurementReporter<double>(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
measurementReporter.Register(m =>
|
||||
{
|
||||
tcs.SetResult();
|
||||
});
|
||||
using var connectionDuration = new MetricCollector<double>(meterFactory, "Microsoft.AspNetCore.Server.Kestrel", "kestrel-connection-duration");
|
||||
|
||||
await host.StartAsync();
|
||||
var client = HttpHelpers.CreateClient();
|
||||
|
@ -103,16 +98,16 @@ public class Http3RequestTests : LoggedTest
|
|||
// 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("Tls13", m.Tags.ToArray().Single(t => t.Key == "tls-protocol").Value);
|
||||
Assert.Equal("HTTP/3", 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("Tls13", m.Tags["tls-protocol"]);
|
||||
Assert.Equal("HTTP/3", m.Tags["http-protocol"]);
|
||||
Assert.Equal($"127.0.0.1:{host.GetPort()}", m.Tags["endpoint"]);
|
||||
});
|
||||
|
||||
await host.StopAsync();
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Quic" />
|
||||
<Reference Include="Microsoft.AspNetCore.WebSockets" />
|
||||
<Reference Include="Microsoft.Extensions.Hosting" />
|
||||
<Reference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
<Reference Include="Microsoft.Internal.AspNetCore.H2Spec.All" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -27,47 +27,3 @@ internal sealed class TestMeterFactory : IMeterFactory
|
|||
Meters.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class MeasurementReporter<T> : IDisposable where T : struct
|
||||
{
|
||||
private readonly string _meterName;
|
||||
private readonly string _instrumentName;
|
||||
private readonly List<Action<Measurement<T>>> _callbacks;
|
||||
private readonly MeterListener _meterListener;
|
||||
|
||||
public MeasurementReporter(IMeterFactory factory, string meterName, string instrumentName, object state = null)
|
||||
{
|
||||
_meterName = meterName;
|
||||
_instrumentName = instrumentName;
|
||||
_callbacks = new List<Action<Measurement<T>>>();
|
||||
_meterListener = new MeterListener();
|
||||
_meterListener.InstrumentPublished = (instrument, listener) =>
|
||||
{
|
||||
if (instrument.Meter.Name == _meterName && instrument.Meter.Scope == factory && instrument.Name == _instrumentName)
|
||||
{
|
||||
listener.EnableMeasurementEvents(instrument, state);
|
||||
}
|
||||
};
|
||||
_meterListener.SetMeasurementEventCallback<T>(OnMeasurementRecorded);
|
||||
_meterListener.Start();
|
||||
}
|
||||
|
||||
private void OnMeasurementRecorded(Instrument instrument, T measurement, ReadOnlySpan<KeyValuePair<string, object>> tags, object state)
|
||||
{
|
||||
var m = new Measurement<T>(measurement, tags);
|
||||
foreach (var callback in _callbacks)
|
||||
{
|
||||
callback(m);
|
||||
}
|
||||
}
|
||||
|
||||
public void Register(Action<Measurement<T>> callback)
|
||||
{
|
||||
_callbacks.Add(callback);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_meterListener.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ using Microsoft.Extensions.Logging;
|
|||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.Extensions.Telemetry.Testing.Metering;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -1091,8 +1092,8 @@ public class HttpConnectionDispatcherTests : VerifiableLoggedTest
|
|||
using (StartVerifiableLog())
|
||||
{
|
||||
var testMeterFactory = new TestMeterFactory();
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-current-connections");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-current-connections");
|
||||
|
||||
var metrics = new HttpConnectionsMetrics(testMeterFactory);
|
||||
var manager = CreateConnectionManager(LoggerFactory, metrics);
|
||||
|
@ -1119,8 +1120,8 @@ public class HttpConnectionDispatcherTests : VerifiableLoggedTest
|
|||
var exists = manager.TryGetConnection(connection.ConnectionId, out _);
|
||||
Assert.False(exists);
|
||||
|
||||
Assert.Collection(connectionDuration.GetMeasurements(), m => AssertDuration(m, HttpConnectionStopStatus.NormalClosure, HttpTransportType.LongPolling));
|
||||
Assert.Collection(currentConnections.GetMeasurements(), m => AssertTransport(m, 1, HttpTransportType.LongPolling), m => AssertTransport(m, -1, HttpTransportType.LongPolling));
|
||||
Assert.Collection(connectionDuration.GetMeasurementSnapshot(), m => AssertDuration(m, HttpConnectionStopStatus.NormalClosure, HttpTransportType.LongPolling));
|
||||
Assert.Collection(currentConnections.GetMeasurementSnapshot(), m => AssertTransport(m, 1, HttpTransportType.LongPolling), m => AssertTransport(m, -1, HttpTransportType.LongPolling));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1147,8 +1148,8 @@ public class HttpConnectionDispatcherTests : VerifiableLoggedTest
|
|||
await dispatcher.ExecuteAsync(context, new HttpConnectionDispatcherOptions(), app);
|
||||
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
|
||||
|
||||
using var connectionDuration = new InstrumentRecorder<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-connection-duration");
|
||||
using var currentConnections = new InstrumentRecorder<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-current-connections");
|
||||
using var connectionDuration = new MetricCollector<double>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-connection-duration");
|
||||
using var currentConnections = new MetricCollector<long>(testMeterFactory, HttpConnectionsMetrics.MeterName, "signalr-http-transport-current-connections");
|
||||
|
||||
await dispatcher.ExecuteAsync(context, new HttpConnectionDispatcherOptions(), app);
|
||||
|
||||
|
@ -1158,22 +1159,22 @@ public class HttpConnectionDispatcherTests : VerifiableLoggedTest
|
|||
var exists = manager.TryGetConnection(connection.ConnectionId, out _);
|
||||
Assert.False(exists);
|
||||
|
||||
Assert.Empty(currentConnections.GetMeasurements());
|
||||
Assert.Empty(connectionDuration.GetMeasurements());
|
||||
Assert.Empty(currentConnections.GetMeasurementSnapshot());
|
||||
Assert.Empty(connectionDuration.GetMeasurementSnapshot());
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertTransport(Measurement<long> measurement, long expected, HttpTransportType transportType)
|
||||
private static void AssertTransport(CollectedMeasurement<long> measurement, long expected, HttpTransportType transportType)
|
||||
{
|
||||
Assert.Equal(expected, measurement.Value);
|
||||
Assert.Equal(transportType.ToString(), (string)measurement.Tags.ToArray().Single(t => t.Key == "transport").Value);
|
||||
Assert.Equal(transportType.ToString(), (string)measurement.Tags["transport"]);
|
||||
}
|
||||
|
||||
private static void AssertDuration(Measurement<double> measurement, HttpConnectionStopStatus status, HttpTransportType transportType)
|
||||
private static void AssertDuration(CollectedMeasurement<double> measurement, HttpConnectionStopStatus status, HttpTransportType transportType)
|
||||
{
|
||||
Assert.True(measurement.Value > 0);
|
||||
Assert.Equal(status.ToString(), (string)measurement.Tags.ToArray().Single(t => t.Key == "status").Value);
|
||||
Assert.Equal(transportType.ToString(), (string)measurement.Tags.ToArray().Single(t => t.Key == "transport").Value);
|
||||
Assert.Equal(status.ToString(), (string)measurement.Tags["status"]);
|
||||
Assert.Equal(transportType.ToString(), (string)measurement.Tags["transport"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<Reference Include="Microsoft.AspNetCore.Http.Connections" />
|
||||
<Reference Include="Microsoft.AspNetCore.Http.Connections.Client" />
|
||||
<Reference Include="Microsoft.AspNetCore.Http" />
|
||||
<Reference Include="Microsoft.Extensions.Telemetry.Testing" />
|
||||
<Reference Include="Newtonsoft.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче