Freigeben über


Protokollierung und Diagnose in ASP.NET Core SignalR

Von Andrew Stanton-Nurse

In diesem Artikel erhalten Sie eine Anleitung, wie Sie Diagnosedaten aus einer ASP.NET Core SignalR-App erhalten, die Sie beim Behandeln von Problemen unterstützen.

Serverseitige Protokollierung

Warning

Serverseitige Protokolle enthalten möglicherweise vertrauliche Daten aus Ihrer App. Veröffentlichten Sie deshalb niemals Protokolle von Produktions-Apps auf öffentlichen Foren wie GitHub.

Da SignalR Teil von ASP.NET Core ist, wird das ASP.NET Core-Protokollierungssystem verwendet. In der Standardkonfiguration protokolliert SignalR minimale Informationen, aber die Protokollierungsebene kann konfiguriert werden. In der Dokumentation zur ASP.NET Core-Protokollierung finden Sie weitere Informationen zum Konfigurieren der ASP.NET Core-Protokollierung.

SignalR bietet zwei Protokollierungskategorien:

  • Microsoft.AspNetCore.SignalR: für Protokolle im Zusammenhang mit Hubprotokollen, dem Aktivieren von Hubs, Aufrufen von Methoden und anderen auf den Hub bezogenen Aktivitäten.
  • Microsoft.AspNetCore.Http.Connections: für Protokolle im Zusammenhang mit Transporten, z. B. WebSockets, lang laufende Abfragen, Server-Sent Events und untergeordneter SignalR-Infrastruktur.

Um detaillierte Protokolle zu SignalR aktivieren, konfigurieren Sie beide oben genannten Präfixe auf die Debug-Ebene in der appsettings.json-Datei, indem Sie dem Unterabschnitt in LogLevel der Logging-Datei die folgenden Elemente hinzufügen:

{
    "Logging": {
        "LogLevel": {
            "Default": "Debug",
            "System": "Information",
            "Microsoft": "Information",
            "Microsoft.AspNetCore.SignalR": "Debug",
            "Microsoft.AspNetCore.Http.Connections": "Debug"
        }
    }
}

Die Protokollierungsebenen für die SignalR Loggerkategorien können auch im Code innerhalb der CreateWebHostBuilder Methode konfiguriert werden:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
            logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
        })
        .UseStartup<Startup>();

Wenn Sie keine JSON-basierte Konfiguration verwenden, legen Sie in Ihrem Konfigurationssystem die folgenden Konfigurationswerte fest:

  • Logging:LogLevel:Microsoft.AspNetCore.SignalR = Debug
  • Logging:LogLevel:Microsoft.AspNetCore.Http.Connections = Debug

Suchen Sie in der Dokumentation nach Informationen zu Ihrem Konfigurationssystem, um zu bestimmen, wie geschachtelte Konfigurationswerte angegeben werden. Bei der Verwendung von Umgebungsvariablen werden beispielsweise zwei _-Zeichen anstelle von : verwendet (z. B. Logging__LogLevel__Microsoft.AspNetCore.SignalR).

Es empfiehlt sich, die Debug-Ebene zu verwenden, wenn detailliertere Diagnosedaten Ihrer App gesammelt werden sollen. Die Trace Ebene erzeugt Diagnosen auf niedriger Ebene und ist selten erforderlich, um Probleme in Ihrer App zu diagnostizieren.

Zugreifen auf serverseitige Protokolle

Der Zugriff auf serverseitige Protokolle hängt von der Umgebung ab, in der die App ausgeführt wird.

Als Konsolen-App außerhalb von IIS

Wenn die Ausführung in einer Konsolen-App stattfindet, sollte die Konsolenprotokollierung standardmäßig aktiviert sein. SignalR Protokolle werden in der Konsole angezeigt.

In IIS Express in Visual Studio

Visual Studio zeigt die Protokollausgabe im Fenster Ausgabe an. Wählen Sie in der Dropdownliste ASP.NET Core-Webserver aus.

Azure App Service

Aktivieren Sie im Azure App Service-Portal im Abschnitt Diagnoseprotokolle die Option Anwendungsprotokollierung (Dateisystem), und legen Sie Ebene auf Verbose fest. Protokolle müssen über den Dienst Protokollstreaming und in Protokollen im Dateisystem der App Service-Instanz verfügbar sein. Weitere Informationen finden Sie unter Azure-Protokollstreaming.

Andere Umgebungen

Weitere Informationen zum Konfigurieren von Protokollierungsanbietern, die für verschiedene Bereitstellungsumgebungen geeignet sind, z. B. Docker, Kubernetes oder Windows-Dienst, finden Sie unter Protokollierung in .NET und ASP.NET Core.

JavaScript-Clientprotokollierung

Warning

Clientseitige Protokolle enthalten möglicherweise vertrauliche Daten aus Ihrer App. Veröffentlichten Sie deshalb niemals Protokolle von Produktions-Apps auf öffentlichen Foren wie GitHub.

Bei Verwenden des JavaScript-Clients können Sie Protokollierungsoptionen mithilfe der configureLogging-Methode für HubConnectionBuilderkonfigurieren:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(signalR.LogLevel.Debug)
    .build();

Deaktivieren Sie die Frameworkprotokollierung, indem Sie signalR.LogLevel.None in der configureLogging Methode angeben. Beachten Sie, dass einige Protokollierungen direkt vom Browser ausgegeben werden und nicht über das Festlegen der Protokollebene deaktiviert werden können.

In der folgenden Tabelle sind die für den JavaScript-Client verfügbaren Protokollebenen aufgeführt. Wenn Sie die Protokollebene auf einen dieser Werte festlegen, wird die Protokollierung auf dieser Ebene und auf allen darüber liegenden Ebenen in der Tabelle aktiviert.

Level Description
None Meldungen werden nicht protokolliert.
Critical Meldungen, die auf einen Fehler in der gesamten App hinweisen.
Error Meldungen, die auf einen Fehler beim aktuellen Vorgang hinweisen.
Warning Meldungen, die auf ein nicht schwerwiegendes Problem hinweisen.
Information Informationsmeldungen.
Debug Für das Debuggen nützliche Diagnosemeldungen.
Trace Sehr detaillierte Diagnosemeldungen, die für die Diagnose bestimmter Probleme vorgesehen sind.

Nachdem Sie die Ausführlichkeit konfiguriert haben, werden die Protokolle in die Browserkonsole (oder die Standardausgabe einer NodeJS-App) geschrieben.

Wenn Sie Protokolle an ein benutzerdefiniertes Protokollierungssystem senden möchten, können Sie ein JavaScript-Objekt bereitstellen, das die ILogger-Schnittstelle implementiert. Die einzige Methode, die implementiert werden muss, ist log, die die Ebene des Ereignisses und die dem Ereignis zugeordnete Meldung verwendet. Beispiel:

import { ILogger, LogLevel, HubConnectionBuilder } from "@microsoft/signalr";

export class MyLogger implements ILogger {
    log(logLevel: LogLevel, message: string) {
        // Use `message` and `logLevel` to record the log message to your own system
    }
}

// later on, when configuring your connection...

let connection = new HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(new MyLogger())
    .build();
import { ILogger, LogLevel, HubConnectionBuilder } from "@aspnet/signalr";

export class MyLogger implements ILogger {
    log(logLevel: LogLevel, message: string) {
        // Use `message` and `logLevel` to record the log message to your own system
    }
}

// later on, when configuring your connection...

let connection = new HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(new MyLogger())
    .build();

.NET-Clientprotokollierung

Warning

Clientseitige Protokolle enthalten möglicherweise vertrauliche Daten aus Ihrer App. Veröffentlichten Sie deshalb niemals Protokolle von Produktions-Apps auf öffentlichen Foren wie GitHub.

Um Protokolle vom .NET-Client abzurufen, können Sie die ConfigureLogging-Methode für HubConnectionBuilderverwenden. Dies funktioniert auf die gleiche Weise wie die ConfigureLogging-Methode für WebHostBuilder und HostBuilder. Sie können die gleichen Protokollierungsanbieter wie in ASP.NET Core konfigurieren. Sie müssen jedoch die NuGet-Pakete für die einzelnen Protokollierungsanbieter manuell installieren und aktivieren.

Informationen zum Hinzufügen der .NET-Clientprotokollierung zu einer Blazor WebAssembly-App finden Sie unter ASP.NET Core Blazor-Protokollierung.

Konsolenprotokollierung

Um die Konsolenprotokollierung zu aktivieren, fügen Sie das Paket Microsoft.Extensions.Logging.Console hinzu. Konfigurieren Sie dann mit der AddConsole-Methode die Konsolenprotokollierung:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to the Console
        logging.AddConsole();

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug);
    })
    .Build();

Debuggen der Protokollierung im Ausgabefenster

Protokolle können so konfiguriert werden, dass sie zum Ausgabefenster in Visual Studio wechseln. Installieren Sie das Paket Microsoft.Extensions.Logging.Debug, und verwenden Sie die AddDebug-Methode:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to the Output Window
        logging.AddDebug();

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug)
    })
    .Build();

Andere Protokollierungsanbieter

SignalR unterstützt andere Protokollierungsanbieter wie Serilog, Seq, NLog oder jedes andere Protokollierungssystem, das sich in Microsoft.Extensions.Logging integrieren lässt. Wenn Ihr Protokollierungssystem einen ILoggerProviderbereitstellt, können Sie ihn mit AddProviderregistrieren:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to your custom provider
        logging.AddProvider(new MyCustomLoggingProvider());

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug)
    })
    .Build();

Steuerung der Ausführlichkeit

Wenn Sie sich von anderen Stellen in der App abmelden, kann das Ändern der Standardebene Debug zu ausführlich sein. Ein Filter kann verwendet werden, um die Protokollierungsebene für SignalR Protokolle zu konfigurieren. Dies kann im Code erfolgen, und zwar auf die gleiche Weise wie auf dem Server:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Register your providers

        // Set the default log level to Information, but to Debug for SignalR-related loggers.
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
        logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
    })
    .Build();

Ablaufverfolgung in SignalR

SignalR Hubserver und der SignalR Client stellen Informationen zu SignalR Verbindungen und Nachrichten bereit, indem sie DiagnosticSource und Activity verwenden. SignalR verfügt über eine ActivitySource für den Hubserver und den Client, die ab .NET 9 verfügbar ist.

Eine ActivitySource ist eine Komponente, die in der verteilten Ablaufverfolgung zum Erstellen und Verwalten von Aktivitäten (oder Spans) verwendet wird, die Vorgänge in Ihrer Anwendung darstellen. Diese Aktivitäten können verwendet werden, um:

  • Verfolgen Sie den Fluss von Anforderungen und Vorgängen über verschiedene Komponenten und Dienste hinweg.
  • Bieten Sie wertvolle Einblicke in die Leistung und das Verhalten Ihrer Anwendung.

.NET SignalR Serveraktivitätsquelle

Die SignalR genannte Microsoft.AspNetCore.SignalR.Server ActivitySource gibt Ereignisse für Hub-Methodenaufrufe aus.

  • Jede Methode ist eine eigene Aktivität, sodass alles, was während des Hubmethodenaufrufs eine Aktivität ausgibt, unter der Hubmethodenaktivität liegt.
  • Hubmethodenaktivitäten verfügen nicht über ein übergeordnetes Element. Dies bedeutet, dass sie nicht unter der langen SignalR Verbindung gebündelt sind.

Im folgenden Beispiel werden das Aspire Dashboard und die OpenTelemetry-Pakete verwendet:

<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />

Fügen Sie der Datei den folgenden Startcode hinzu Program.cs :

using OpenTelemetry.Trace;
using SignalRChat.Hubs;

// Set OTEL_EXPORTER_OTLP_ENDPOINT environment variable depending on where your OTEL endpoint is.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        if (builder.Environment.IsDevelopment())
        {
            // View all traces only in development environment.
            tracing.SetSampler(new AlwaysOnSampler());
        }

        tracing.AddAspNetCoreInstrumentation();
        tracing.AddSource("Microsoft.AspNetCore.SignalR.Server");
    });

builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => tracing.AddOtlpExporter());

var app = builder.Build();

Die folgende Beispielausgabe stammt aus dem Aspire Dashboard:

Aktivitätsliste für SignalR Hub-Methodenaufrufereignisse

ASP.NET Core stellt auch eigene Metriken für Microsoft.AspNetCore.Hosting die Ereignisquelle bereit.

.NET-Clientaktivitätsquelle SignalR

Der SignalRActivitySource mit dem Namen Microsoft.AspNetCore.SignalR.Client gibt Ereignisse für einen SignalR-Client aus.

  • Hubaufrufe erstellen eine Clientspanne. Andere SignalR Clients, z. B. der JavaScript-Client, unterstützen die Ablaufverfolgung nicht. Dieses Feature wird weiteren Clients in zukünftigen Versionen hinzugefügt.
  • Hubaufrufe auf dem Client und server unterstützen die Kontextverteilung. Das Verteilen des Ablaufverfolgungskontexts ermöglicht die echte verteilte Ablaufverfolgung. Es ist jetzt möglich, Aufrufe vom Client zum Server und zurück zu sehen.

Hier erfahren Sie, wie diese neuen Aktivitäten im Aspire Dashboard aussehen:

SignalR Verteilte Ablaufverfolgung im Aspire Dashboard

Netzwerkablaufverfolgungen

Warning

Eine Netzwerkablaufverfolgung enthält den vollständigen Inhalt jeder Nachricht, die von Ihrer App gesendet wird. Veröffentlichten Sie deshalb niemals unbearbeitete Netzwerkablaufverfolgungen von Produktions-Apps in öffentlichen Foren wie GitHub.

Wenn ein Problem auftritt, kann eine Netzwerkablaufverfolgung manchmal wertvolle Informationen bereitstellen. Dies ist besonders hilfreich bei der Einreichung eines Problems auf unserer Problemverfolgung.

Erfassen einer Netzwerküberwachung mit Fiddler (bevorzugte Option)

Diese Methode kann für alle Apps angewendet werden.

Fiddler ist ein leistungsstarkes Tool zum Erfassen von HTTP-Ablaufverfolgungen. Installieren Sie es von telerik.com/fiddler, starten Sie es, und führen Sie dann Ihre App aus, und reproduzieren Sie das Problem. Fiddler ist für Windows verfügbar, für macOS und Linux gibt es Betaversionen.

Wenn Sie eine Verbindung über HTTPS herstellen, gibt es einige zusätzliche Schritte, um sicherzustellen, dass Fiddler den HTTPS-Datenverkehr entschlüsseln kann. Weitere Informationen finden Sie in der Fiddler-Dokumentation.

Nachdem Sie die Ablaufverfolgung gesammelt haben, exportieren Sie sie, indem Sie in der Menüleiste Datei>Speichern>Alle Sitzungen auswählen.

Exportieren aller Sitzungen aus Fiddler

Erfassen einer Netzwerkablaufverfolgung mit tcpdump (nur macOS und Linux)

Diese Methode kann für alle Apps angewendet werden.

Unformatierte TCP-Daten können mithilfe von tcpdump gesammelt werden, indem Sie den folgenden Befehl von einer Befehlsshell ausführen. Möglicherweise müssen Sie dies als root-Benutzer tun oder dem Befehl sudo als Präfix voranstellen, wenn Sie einen Berechtigungsfehler erhalten:

tcpdump -i [interface] -w trace.pcap

Ersetzen [interface] Sie durch die Netzwerkschnittstelle, an der Sie die Erfassung durchführen möchten. In der Regel entspricht /dev/eth0 dies (für eine Standard-Ethernet-Schnittstelle) oder /dev/lo0 (für localhost-Datenverkehr). Weitere Informationen finden Sie auf der tcpdump manuellen Seite ihres Hostsystems.

Erfassen einer Netzwerkablaufverfolgung im Browser

Diese Methode funktioniert nur für browserbasierte Apps.

Die meisten Browserentwicklertools-Konsolen verfügen über eine Registerkarte "Netzwerk", über die Netzwerkaktivitäten zwischen dem Browser und dem Server erfasst werden können. Diese Überwachungen enthalten jedoch keine WebSocket- und Server-Sent Event-Nachrichten. Bei der Verwendung dieser Transporte ist die Verwendung eines Tools wie Fiddler oder TcpDump ein besserer Ansatz, wie weiter unten in diesem Artikel beschrieben.

Microsoft Edge und Internet Explorer

(Die Anweisungen sind für Microsoft Edge und Internet Explorer identisch)

  1. Öffnen Sie die Dev Tools, indem Sie F12 drücken
  2. Wählen Sie die Registerkarte "Netzwerk" aus.
  3. Aktualisieren Sie die Seite (falls erforderlich), und reproduzieren Sie das Problem.
  4. Wählen Sie auf der Symbolleiste das Symbol "Speichern" aus, um die Ablaufverfolgung als HAR-Datei zu exportieren:

Das Symbol „Speichern“ auf der Registerkarte „Netzwerk“ in den Microsoft Edge-Entwicklertools

Google Chrome

  1. Öffnen Sie die Dev Tools, indem Sie F12 drücken
  2. Wählen Sie die Registerkarte "Netzwerk" aus.
  3. Aktualisieren Sie die Seite (falls erforderlich), und reproduzieren Sie das Problem.
  4. Klicken Sie mit der rechten Maustaste in der Liste der Anforderungen auf eine beliebige Stelle, und wählen Sie „Als HAR mit Inhalt speichern“ aus.

Option „Als HAR mit Inhalt speichern“ auf der Registerkarte „Netzwerk“ in den Google Chrome-Entwicklertools

Mozilla Firefox

  1. Öffnen Sie die Dev Tools, indem Sie F12 drücken
  2. Wählen Sie die Registerkarte "Netzwerk" aus.
  3. Aktualisieren Sie die Seite (falls erforderlich), und reproduzieren Sie das Problem.
  4. Klicken Sie mit der rechten Maustaste auf eine beliebige Stelle in der Liste der Anforderungen, und wählen Sie „Alle als HAR speichern“ aus.

Option „Alle als HAR speichern“ auf der Registerkarte „Netzwerk“ in den Mozilla Firefox-Entwicklertools

Anfügen von Diagnosedateien an GitHub-Issues

Diagnostikdateien können an GitHub-Probleme angefügt werden, indem sie umbenannt werden, sodass sie eine .txt Erweiterung erhalten und dann auf das Problem gezogen und abgelegt werden.

Note

Fügen Sie den Inhalt von Protokolldateien oder Netzwerküberwachungen nicht in ein GitHub-Issue ein. Diese Protokolle und Ablaufverfolgungen können groß sein, und GitHub kürzt sie normalerweise automatisch.

Ziehen von Protokolldateien auf ein GitHub-Issue

Metrics

Metriken sind eine Darstellung von Datenmaßen über Zeitintervalle. Beispielsweise Anforderungen pro Sekunde. Metrikdaten ermöglichen die Überwachung des Zustands einer App auf einer hohen Ebene. .NET-gRPC-Metriken werden mithilfe von EventCounter ausgegeben.

SignalR-Servermetriken

SignalR-Servermetriken werden für die Ereignisquelle Microsoft.AspNetCore.Http.Connections gemeldet.

Name Description
connections-started Gestartete Verbindungen insgesamt
connections-stopped Beendete Verbindungen insgesamt
connections-timed-out Verbindungen mit Timeout insgesamt
current-connections Aktuelle Verbindungen
connections-duration Durchschnittliche Verbindungsdauer

Metriken beobachten

dotnet-counters ist ein Leistungsüberwachungstool zur Ad-hoc-Überwachung der Integrität und zur Leistungsuntersuchung auf erster Ebene. Sie können eine .NET-App mit Microsoft.AspNetCore.Http.Connections als Anbietername überwachen. Beispiel:

> dotnet-counters monitor --process-id 37016 --counters Microsoft.AspNetCore.Http.Connections

Press p to pause, r to resume, q to quit.
    Status: Running
[Microsoft.AspNetCore.Http.Connections]
    Average Connection Duration (ms)       16,040.56
    Current Connections                         1
    Total Connections Started                   8
    Total Connections Stopped                   7
    Total Connections Timed Out                 0

Weitere Ressourcen