Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Metriken sind numerische Werte, die im Laufe der Zeit erfasst werden. Sie werden in der Regel verwendet, um den Status einer App zu überwachen und Warnungen zu generieren.
Ab .NET 8 werden die System.Net.Http und System.Net.NameResolution Komponenten instrumentiert, um Metriken mithilfe der neuen .NET System.Diagnostics.Metrics APIzu veröffentlichen.
Diese Metriken wurden in Zusammenarbeit mit OpenTelemetry entwickelt, um sicherzustellen, dass sie mit dem Standard konsistent sind und gut mit beliebten Tools wie Prometheus und Grafanafunktionieren.
Sie sind auch mehrdimensional, was bedeutet, dass Messwerte Schlüssel-Wert-Paaren zugeordnet sind, die als Tags bezeichnet werden (auch als Attribute oder Beschriftungen bezeichnet). Tags ermöglichen die Kategorisierung der Messung, um die Analyse zu unterstützen.
Tipp
Eine umfassende Liste aller integrierten Instrumente zusammen mit ihren Attributen finden Sie unter System.Net Metriken.
Sammeln System.Net Metriken
Um die integrierte Metrikinstrumentation nutzen zu können, muss eine .NET-App so konfiguriert werden, dass diese Metriken erfasst werden. Dies bedeutet in der Regel, sie für externe Speicher und Analysen zu transformieren, z. B. in Überwachungssysteme.
Es gibt mehrere Möglichkeiten zum Sammeln von Netzwerkmetriken in .NET.
- Eine kurze Übersicht mithilfe eines einfachen, eigenständigen Beispiels finden Sie unter Sammeln von Metriken mit dotnet-counters.
- Für die Sammlung und Überwachung von Metriken zur Produktionszeit können Sie Grafana mit OpenTelemetry und Prometheus oder Azure Monitor Application Insights verwenden. Diese Tools können jedoch aufgrund ihrer Komplexität bei der Entwicklung unpraktisch sein.
- Für die Sammlung und Problembehandlung von Entwicklungsmetriken empfehlen wir die Verwendung Aspire, die eine einfache, aber erweiterbare Möglichkeit bietet, Metriken und verteilte Ablaufverfolgung in Ihrer Anwendung zu starten und Probleme lokal zu diagnostizieren.
- Es ist auch möglich, das Projekt Aspire Service Defaults ohne die Aspire Orchestrierung wiederzuverwenden, was eine praktische Möglichkeit ist, die OpenTelemetry tracing und metrics configuration APIs in Ihr ASP.NET-Projekt einzuführen.
Sammeln von Metriken mit Dotnet-Zählern
dotnet-counters ist ein plattformübergreifendes Befehlszeilentool zur Ad-hoc-Untersuchung von .NET-Metriken und Leistungsuntersuchungen auf erster Ebene.
Erstellen Sie für dieses Lernprogramm eine App, die HTTP-Anforderungen parallel an verschiedene Endpunkte sendet.
dotnet new console -o HelloBuiltinMetrics
cd ..\HelloBuiltinMetrics
Ersetzen Sie den Inhalt von Program.cs durch den folgenden Beispielcode:
using System.Net;
string[] uris = ["http://example.com", "http://httpbin.org/get", "https://example.com", "https://httpbin.org/get"];
using HttpClient client = new()
{
DefaultRequestVersion = HttpVersion.Version20
};
Console.WriteLine("Press any key to start.");
Console.ReadKey();
while (!Console.KeyAvailable)
{
await Parallel.ForAsync(0, Random.Shared.Next(20), async (_, ct) =>
{
string uri = uris[Random.Shared.Next(uris.Length)];
try
{
byte[] bytes = await client.GetByteArrayAsync(uri, ct);
await Console.Out.WriteLineAsync($"{uri} - received {bytes.Length} bytes.");
}
catch { await Console.Out.WriteLineAsync($"{uri} - failed."); }
});
}
Stellen Sie sicher, dass dotnet-counters installiert ist:
dotnet tool install --global dotnet-counters
Starten Sie die HelloBuiltinMetrics-App.
dotnet run -c Release
Starten Sie dotnet-counters in einem separaten CLI-Fenster, und geben Sie den Prozessnamen und die zu überwachenden Meter an, und drücken Sie dann in der HelloBuiltinMetrics-App eine Taste, damit das Senden von Anforderungen gestartet wird. Sobald die Messungen eintreffen, aktualisiert dotnet-counters kontinuierlich die Konsole mit den neuesten Werten.
dotnet-counters monitor --counters System.Net.Http,System.Net.NameResolution -n HelloBuiltinMetrics
Sammeln von Metriken mit Aspire
Eine einfache Möglichkeit zum Sammeln von Ablaufverfolgungen und Metriken in ASP.NET-Anwendungen besteht darin, Aspire zu verwenden. Aspire ist eine Reihe von Erweiterungen für .NET, um das Erstellen und Arbeiten mit verteilten Anwendungen zu vereinfachen. Einer der Vorteile der Verwendung von Aspire besteht darin, dass Telemetrie integriert ist und die OpenTelemetry-Bibliotheken für .NET verwendet werden.
Die Standardprojektvorlagen für Aspire enthalten ein ServiceDefaults Projekt. Jeder Dienst in der Aspire Lösung weist einen Verweis auf das Projekt "Dienststandards" auf. Die Dienste verwenden sie zum Einrichten und Konfigurieren von OTel.
Die Projektvorlage "Dienststandard" enthält die OTel-SDK-, ASP.NET-, HttpClient- und Runtime Instrumentation-Pakete. Diese Instrumentierungskomponenten sind in der datei Extensions.cs konfiguriert. Zur Unterstützung der Telemetrievisualisierung im Aspire Dashboard enthält das Service Defaults-Projekt auch standardmäßig den OTLP-Exporter.
Aspire Das Dashboard ist so konzipiert, dass Telemetriebeobachtungen in den lokalen Debugzyklus übertragen werden, sodass Entwickler sicherstellen können, dass die Anwendungen Telemetrie erzeugen. Die Telemetrievisualisierung hilft auch, diese Anwendungen lokal zu diagnostizieren. Die Möglichkeit, die Aufrufe zwischen Diensten zu beobachten, ist zum Debugzeitpunkt so nützlich wie in der Produktion. Das Aspire Dashboard wird automatisch gestartet, wenn Sie F5 das AppHost Projekt von Visual Studio oder dotnet run das AppHost Projekt über die Befehlszeile ausführen.
Exemplarische Vorgehensweise
Erstellen einer Aspire 9 Starter-App mithilfe von
dotnet new:dotnet new aspire-starter-9 --output AspireDemoOder erstellen Sie in Visual Studio ein neues Projekt, und wählen Sie die Vorlage Aspire 9 Starter App aus:
Öffnen Sie
Extensions.csimServiceDefaultsProjekt, und scrollen Sie zurConfigureOpenTelemetryMethode. Beachten Sie denAddHttpClientInstrumentation()-Aufruf, der die Networking-Meter abonniert..WithMetrics(metrics => { metrics.AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddRuntimeInstrumentation(); })Beachten Sie, dass auf .NET 8+
AddHttpClientInstrumentation()durch manuelle Meterabonnements ersetzt werden können:.WithMetrics(metrics => { metrics.AddAspNetCoreInstrumentation() .AddMeter("System.Net.Http") .AddMeter("System.Net.NameResolution") .AddRuntimeInstrumentation(); })Führen Sie das
AppHostProjekt aus. Dadurch sollte das Aspire Dashboard gestartet werden.Navigieren Sie zur Seite Wetter der
webfrontendApp, um eineHttpClientAnfrage in Richtungapiservicezu generieren. Aktualisieren Sie die Seite mehrmals, um mehrere Anfragen zu senden.Kehren Sie zum Dashboard zurück, navigieren Sie zur Seite Metriken, und wählen Sie die
webfrontendRessource aus. Wenn Sie nach unten scrollen, sollten Sie in der Lage sein, die integriertenSystem.NetMetriken zu durchsuchen.
Weitere Informationen zu Aspire finden Sie unter:
- Aspire Übersicht
- Telemetrie in Aspire
- Aspire Dashboard
Service Defaults-Projekt ohne Aspire-Orchestrierung wiederverwenden
Das Projekt "Aspire Service Defaults" bietet eine einfache Möglichkeit zum Konfigurieren von OTel für ASP.NET-Projekte, auch wenn der Rest von Aspire, wie z. B. der AppHost für die Orchestrierung, nicht verwendet wird. Das Dienststandardprojekt ist als Projektvorlage über Visual Studio oder dotnet newverfügbar. Er konfiguriert OTel und richtet den OTLP-Exporter ein. Anschließend können Sie die OTel-Umgebungsvariablen verwenden, um den OTLP-Endpunkt zum Senden von Telemetrie zu konfigurieren und die Ressourceneigenschaften für die Anwendung bereitzustellen.
Die Schritte zur Verwendung von ServiceDefaults außerhalb von Aspire :
Fügen Sie das Projekt ServiceDefaults mithilfe von "Neues Projekt hinzufügen" in Visual Studio zur Projektmappe hinzu, oder verwenden Sie
dotnet new:dotnet new aspire-servicedefaults --output ServiceDefaultsVerweisen Sie auf das ServiceDefaults- Projekt aus Ihrer ASP.NET Anwendung. Wählen Sie in Visual Studio Hinzufügen>Projektreferenz und wählen Sie das ServiceDefaults-Projekt"
Rufen Sie die OpenTelemetry-Setupfunktion
ConfigureOpenTelemetry()als Teil der Initialisierung des Anwendungs-Generators auf.var builder = WebApplication.CreateBuilder(args) builder.ConfigureOpenTelemetry(); // Extension method from ServiceDefaults. var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
Eine vollständige exemplarische Vorgehensweise finden Sie unter Beispiel: Verwenden von OpenTelemetry mit OTLP und dem eigenständigen Aspire Dashboard.
Anzeigen von Metriken in Grafana mit OpenTelemetry und Prometheus
Um zu sehen, wie Sie eine Beispiel-App mit Prometheus und Grafana verbinden, befolgen Sie die exemplarische Vorgehensweise in Verwenden von OpenTelemetry mit Prometheus, Grafana und Jaeger.
Um HttpClient zu betonen, indem parallele Anforderungen an verschiedene Endpunkte gesendet werden, erweitern Sie die Beispiel-App mit dem folgenden Endpunkt:
app.MapGet("/ClientStress", async Task<string> (ILogger<Program> logger, HttpClient client) =>
{
string[] uris = ["http://example.com", "http://httpbin.org/get", "https://example.com", "https://httpbin.org/get"];
await Parallel.ForAsync(0, 50, async (_, ct) =>
{
string uri = uris[Random.Shared.Next(uris.Length)];
try
{
await client.GetAsync(uri, ct);
logger.LogInformation($"{uri} - done.");
}
catch { logger.LogInformation($"{uri} - failed."); }
});
return "Sent 50 requests to example.com and httpbin.org.";
});
Erstellen Sie ein Grafana-Dashboard, indem Sie auf der oberen Symbolleiste das symbol + und dann Dashboard-auswählen. Geben Sie im daraufhin angezeigten Dashboard-Editor Open HTTP/1.1 Connections in das Feld Titel und die folgende Abfrage im Feld „PromQL-Ausdruck“ ein:
sum by(http_connection_state) (http_client_open_connections{network_protocol_version="1.1"})
Klicken Sie auf Anwenden, um das neue Dashboard zu speichern und anzuzeigen. Es zeigt die Anzahl aktiver und leerer HTTP/1.1-Verbindungen im Pool an.
Anreicherung
Anreicherung ist das Hinzufügen von angepassten Tags (auch bekannt als Attribute oder Kennzeichnungen) zu einer Metrik. Dies ist nützlich, wenn eine App eine benutzerdefinierte Kategorisierung zu Dashboards oder Warnungen hinzufügen möchte, die mit Metriken erstellt wurden.
Das http.client.request.duration-Instrument unterstützt die Anreicherung durch Registrieren von Rückrufen bei der HttpMetricsEnrichmentContext.
Beachten Sie, dass dies eine API mit niedriger Ebene ist und für jede HttpRequestMessageeine separate Rückrufregistrierung erforderlich ist.
Eine einfache Möglichkeit, die Rückrufregistrierung an einem zentralen Ort durchzuführen, besteht darin, eine benutzerdefinierte DelegatingHandlerzu implementieren. Auf diese Weise können Sie die Anforderungen abfangen und ändern, bevor sie an den inneren Handler weitergeleitet und an den Server gesendet werden:
using System.Net.Http.Metrics;
using HttpClient client = new(new EnrichmentHandler() { InnerHandler = new HttpClientHandler() });
await client.GetStringAsync("https://httpbin.org/response-headers?Enrichment-Value=A");
await client.GetStringAsync("https://httpbin.org/response-headers?Enrichment-Value=B");
sealed class EnrichmentHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpMetricsEnrichmentContext.AddCallback(request, static context =>
{
if (context.Response is not null) // Response is null when an exception occurs.
{
// Use any information available on the request or the response to emit custom tags.
string? value = context.Response.Headers.GetValues("Enrichment-Value").FirstOrDefault();
if (value != null)
{
context.AddCustomTag("enrichment_value", value);
}
}
});
return base.SendAsync(request, cancellationToken);
}
}
Wenn Sie mit IHttpClientFactoryarbeiten, können Sie AddHttpMessageHandler verwenden, um die EnrichmentHandlerzu registrieren:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Net.Http.Metrics;
ServiceCollection services = new();
services.AddHttpClient(Options.DefaultName).AddHttpMessageHandler(() => new EnrichmentHandler());
ServiceProvider serviceProvider = services.BuildServiceProvider();
HttpClient client = serviceProvider.GetRequiredService<HttpClient>();
await client.GetStringAsync("https://httpbin.org/response-headers?Enrichment-Value=A");
await client.GetStringAsync("https://httpbin.org/response-headers?Enrichment-Value=B");
Anmerkung
Aus Leistungsgründen wird der Anreicherungsrückruf nur aufgerufen, wenn das http.client.request.duration-Instrument aktiviert ist, was bedeutet, dass etwas die Metriken erfasst.
Dies kann dotnet-monitor, Prometheus-Exporter, ein MeterListeneroder ein MetricCollector<T> sein.
IMeterFactory und IHttpClientFactory Integration
HTTP-Metriken wurden mit Isolation und Testbarkeit entworfen. Diese Aspekte werden durch die Verwendung von IMeterFactoryunterstützt, die es ermöglicht, Metriken über eine benutzerdefinierte Meter Instanz zu veröffentlichen, um die Meter voneinander isoliert zu halten.
Standardmäßig wird ein globales Meter verwendet, um alle Metriken auszugeben. Dies Meter intern in der System.Net.Http-Bibliothek. Dieses Verhalten kann durch Zuweisung einer angepassten IMeterFactory-Instanz an SocketsHttpHandler.MeterFactory oder HttpClientHandler.MeterFactory außer Kraft gesetzt werden.
Anmerkung
Meter.Name ist System.Net.Http für alle Metriken, die von HttpClientHandler und SocketsHttpHandler ausgegeben werden.
Wenn Sie mit Microsoft.Extensions.Http und IHttpClientFactory auf .NET 8+ arbeiten, wählt die standardimplementierung IHttpClientFactory automatisch die im IMeterFactory registrierte IServiceCollection-Instanz aus und weist sie dem primären Handler zu, den sie intern erstellt.
Anmerkung
Ab .NET 8 ruft die AddHttpClient-Methode automatisch AddMetrics auf, um die Metrikdienste zu initialisieren und die Standardimplementierung IMeterFactory bei IServiceCollectionzu registrieren. Die Voreinstellung IMeterFactory zwischenspeichert Meter-Instanzen nach Namen, was bedeutet, dass es pro IServiceCollection eine Meter-Instanz mit dem Namen System.Net.Http gibt.
Testmetriken
Im folgenden Beispiel wird veranschaulicht, wie integrierte Metriken in Komponententests mithilfe von xUnit, IHttpClientFactoryund MetricCollector<T> aus dem Microsoft.Extensions.Diagnostics.Testing NuGet-Paket überprüft werden:
[Fact]
public async Task RequestDurationTest()
{
// Arrange
ServiceCollection services = new();
services.AddHttpClient();
ServiceProvider serviceProvider = services.BuildServiceProvider();
var meterFactory = serviceProvider.GetService<IMeterFactory>();
var collector = new MetricCollector<double>(meterFactory,
"System.Net.Http", "http.client.request.duration");
var client = serviceProvider.GetRequiredService<HttpClient>();
// Act
await client.GetStringAsync("http://example.com");
// Assert
await collector.WaitForMeasurementsAsync(minCount: 1).WaitAsync(TimeSpan.FromSeconds(5));
Assert.Collection(collector.GetMeasurementSnapshot(),
measurement =>
{
Assert.Equal("http", measurement.Tags["url.scheme"]);
Assert.Equal("GET", measurement.Tags["http.request.method"]);
});
}
Metriken im Vergleich zu EventCounters
Metriken sind funktionsreicher als die EventCounters, vor allem wegen ihrer mehrdimensionalen Natur. Mit dieser mehrdimensionalen Eigenschaft können Sie komplexe Abfragen in Tools wie Prometheus erstellen und Einblicke auf eine Ebene erhalten, die mit EventCounters nicht möglich ist.
Ab .NET 8 werden jedoch nur die System.Net.Http und die System.Net.NameResolutions Komponenten mithilfe von Metriken instrumentiert, was bedeutet, dass Sie bei Bedarf Zähler aus den unteren Ebenen des Stapels wie System.Net.Sockets oder System.Net.Securitybenötigen, müssen Sie EventCounters verwenden.
Darüber hinaus gibt es einige semantische Unterschiede zwischen Metriken und deren übereinstimmenden EventCounters.
Wenn Sie z. B. HttpCompletionOption.ResponseContentReadverwenden, betrachtet das current-requests EventCounter eine Aktive Anforderung bis zum Zeitpunkt, in dem das letzte Byte des Anforderungstexts gelesen wurde.
Die Kennzahl http.client.active_requests enthält nicht die Zeit, die für das Lesen des Antwortinhalts aufgewendet wird, wenn die aktiven Anfragen gezählt werden.
Benötigen Sie weitere Metriken?
Wenn Sie Vorschläge für andere nützliche Informationen haben, die über Metriken verfügbar gemacht werden könnten, erstellen Sie einen Issue in dotnet/runtime.