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 Erfassung und Problembehandlung von Entwicklungsmetriken empfehlen wir die Verwendung von 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 Aspire Service Defaults Projekt ohne die Aspire Orchestrierung wiederzuverwenden. Dies ist eine praktische Möglichkeit, die OpenTelemetry Tracing- und Metrik-Konfigurations-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, Ablaufverfolgungen und Metriken in ASP.NET-Anwendungen zu sammeln, ist, Aspire zu verwenden. Aspire ist eine Reihe von Erweiterungen für .NET, um das Erstellen und Arbeiten mit verteilten Anwendungen zu erleichtern. Einer der Vorteile der Verwendung von Aspire ist, dass Telemetrie integriert ist, indem 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 "Service Defaults" 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 Dienststandardprojekt standardmäßig auch den OTLP-Exporter.
Das Aspire Dashboard wurde entwickelt, um Telemetriebeobachtungen in den lokalen Debugzyklus zu bringen, wodurch 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 das Projekt in Visual Studio mit F5 oder das dotnet run Projekt über die Befehlszeile starten.
Exemplarische Vorgehensweise
Erstellen Sie eine 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:
Voreinstellungen für Dienstprojekte ohne Aspire-Orchestrierung wiederverwenden
Das Projekt "Aspire Service Defaults" bietet eine einfache Möglichkeit, OTel für ASP.NET Projekte zu konfigurieren, auch wenn der Rest von Aspire nicht verwendet wird, z. B. appHost für die Orchestrierung. 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 sind:
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 Meter eine System.Net.Http-Instanz mit dem Namen IServiceCollection 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.