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

Warnung

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 nur sehr wenige Informationen, was jedoch konfigurierbar ist. 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 eine ausführliche Protokollierung von SignalR zu ermöglichen, konfigurieren Sie die beiden vorherigen Präfixe auf der Ebene Debug Ihrer Datei appsettings.json, indem Sie die folgenden Elemente zum Unterabschnitt LogLevel in Logging hinzufügen:

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

Sie können dies auch im Code Ihrer CreateWebHostBuilder -Methode konfigurieren:

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 bietet nur sehr wenige Diagnoseinformationen und wird nur selten verwendet, um App-Probleme zu identifizieren.

Zugreifen auf serverseitige Protokolle

Wie Sie auf serverseitige Protokolle zugreifen können, hängt von der Ausführungsumgebung ab.

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

Wenn die App in einer anderen Umgebung bereitgestellt wird (z. B. Docker, Kubernetes oder Windows-Dienst) finden Sie unter Protokollieren in .NET Core und ASP.NET Core weitere Informationen zum Konfigurieren von Protokollierungsanbietern, die für die Umgebung geeignet sind.

JavaScript-Clientprotokollierung

Warnung

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();

Um die Frameworkprotokollierung zu deaktivieren, geben Sie signalR.LogLevel.None in der configureLogging-Methode an. 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.

Ebene Beschreibung
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

Warnung

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

Sie können die Protokolle auch so konfigurieren, dass sie in Visual Studio im Fenster Ausgabe angezeigt werden. 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();

Steuern der Ausführlichkeit

Wenn Sie von anderen Stellen in Ihrer App aus protokollieren, ist das Ändern der Standardebene in Debug möglicherweise zu ausführlich. Sie können die Protokollebene für SignalR-Protokolle mithilfe eines Filters 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();

Netzwerkablaufverfolgung

Warnung

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 Netzwerküberwachung mitunter viele hilfreiche Informationen liefern. Dies ist besonders nützlich, wenn Sie ein Problem in unserem Issue Tracker melden möchten.

Erfassen einer Netzwerküberwachung mit Fiddler (bevorzugte Option)

Diese Methode kann für alle Apps angewendet werden.

Fiddler ist ein sehr leistungsstarkes Tool zum Erfassen von HTTP-Überwachungen. 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 Dokumentation zu Fiddler.

Nachdem Sie die Ablaufverfolgung erfasst haben, können Sie die Ablaufverfolgung exportieren, 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.

Sie können unformatierte TCP-Ablaufverfolgungen mithilfe von tcpdump erfassen, indem Sie den folgenden Befehl in 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 ist dies etwas wie /dev/eth0 (für Ihre Ethernet-Standardschnittstelle) oder /dev/lo0 (für localhost-Datenverkehr). Weitere Informationen finden Sie auf der Manpage zu tcpdump auf Ihrem Hostsystem.

Erfassen einer Netzwerkablaufverfolgung im Browser

Diese Methode funktioniert nur für browserbasierte Apps.

Die meisten Konsolen mit Entwicklertools in Browsern weisen die Registerkarte „Netzwerk“ auf, über die Sie die Netzwerkaktivität zwischen Browser und Server erfassen können. Diese Überwachungen enthalten jedoch keine WebSocket- und Server-Sent Event-Nachrichten. Wenn Sie diese Transporte verwenden, ist ein Tool wie Fiddler oder TcpDump (nachstehend beschrieben) möglicherweise besser geeignet.

Microsoft Edge und Internet Explorer

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

  1. Drücken Sie F12, um die Entwicklertools zu öffnen.
  2. Klicken Sie auf die Registerkarte „Netzwerk“.
  3. Aktualisieren Sie die Seite (falls erforderlich), und reproduzieren Sie das Problem.
  4. Klicken Sie auf der Symbolleiste auf das Symbol „Speichern“, um die Überwachung als HAR-Datei zu speichern:

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

Google Chrome

  1. Drücken Sie F12, um die Entwicklertools zu öffnen.
  2. Klicken Sie auf die Registerkarte „Netzwerk“.
  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. Drücken Sie F12, um die Entwicklertools zu öffnen.
  2. Klicken Sie auf die Registerkarte „Netzwerk“.
  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

Sie können Diagnosedateien an GitHub-Issues anfügen, indem Sie sie mit der Erweiterung .txt umbenennen und dann per Drag & Drop auf das betreffende Issue ziehen.

Hinweis

Fügen Sie den Inhalt von Protokolldateien oder Netzwerküberwachungen nicht in ein GitHub-Issue ein. Diese Protokolle und Überwachungen können recht groß sein und werden von GitHub normalerweise abgeschnitten.

Ziehen von Protokolldateien auf ein GitHub-Issue

Metriken

Bei Metriken handelt es sich um eine Darstellung von Datenmesswerten in bestimmten Zeiträumen. 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 Beschreibung
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

Überwachen von Metriken

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 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

Zusätzliche Ressourcen