Partager via


Journalisation et diagnostics dans ASP.NET Core SignalR

Par Andrew Stanton-Nurse

Cet article fournit des conseils pour la collecte de diagnostics à partir de votre application ASP.NET Core SignalR pour aider à résoudre des problèmes.

Journalisation côté serveur

Avertissement

Les journaux côté serveur peuvent contenir des informations sensibles de votre application. Ne publiez jamais les journaux bruts des applications de production sur des forums publics comme GitHub.

Étant donné que SignalR fait partie d’ASP.NET Core, il utilise le système de journalisation ASP.NET Core. Dans la configuration par défaut, SignalR enregistre des informations minimales, mais le niveau de journalisation peut être configuré. Pour plus d’informations sur la configuration de la journalisation ASP.NET Core, consultez la documentation sur la Journalisation ASP.NET Core.

SignalR utilise deux catégories d’enregistreurs d’événements :

  • Microsoft.AspNetCore.SignalR : pour les journaux liés aux protocoles hub, l’activation de hubs, l’appel de méthodes et d’autres activités liées au hub.
  • Microsoft.AspNetCore.Http.Connections : pour les journaux liés aux transports, tels que WebSockets, l’interrogation longue, les événements envoyés par serveur et l’infrastructure SignalR de bas niveau.

Pour activer les journaux détaillés à partir de SignalR, configurez les deux préfixes précédents au niveau Debug dans votre fichier appsettings.json en ajoutant les éléments suivants à la sous-section LogLevel dans Logging:

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

Les niveaux de journalisation des catégories d'enregistreurs SignalR peuvent également être configurés dans le code via la méthode CreateWebHostBuilder :

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

Si vous n’utilisez pas la configuration basée sur JSON, définissez les valeurs de configuration suivantes dans votre système de configuration :

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

Consultez la documentation de votre système de configuration pour déterminer comment spécifier des valeurs de configuration imbriquées. Par exemple, lors de l’utilisation de variables d’environnement, deux caractères _ sont utilisés à la place de : (par exemple Logging__LogLevel__Microsoft.AspNetCore.SignalR).

Nous vous recommandons d’utiliser le niveau Debug lors de la collecte de diagnostics plus détaillés pour votre application. Le Trace niveau produit des diagnostics de bas niveau et est rarement nécessaire pour diagnostiquer les problèmes dans votre application.

Accéder aux journaux côté serveur

La façon dont le journal côté serveur est accessible dépend de l’environnement dans lequel l’application s’exécute.

En tant qu’application console en dehors d’IIS

Si vous exécutez dans une application console, l’enregistreur d’événements de console doit être activé par défaut. SignalR les journaux s’affichent dans la console.

Dans IIS Express à partir de Visual Studio

Visual Studio affiche la sortie du journal dans la fenêtre Sortie. Sélectionnez l’option Serveur web ASP.NET Core dans la liste déroulante.

Azure App Service

Activez l’option Journalisation des applications (système de fichiers) dans la section Journaux de diagnostics du portail Azure App Service et configurez le Niveau sur Verbose. Les journaux doivent être disponibles à partir du service de Streaming des journaux et dans les journaux sur le système de fichiers App Service. Pour plus d’informations, consultez Streaming de journaux Azure.

Autres environnements

Pour plus d’informations sur la configuration des fournisseurs de journalisation adaptés à différents environnements de déploiement, tels que Docker, Kubernetes ou Windows Service, consultez Journalisation dans .NET Core et ASP.NET Core.

Journalisation du client JavaScript

Avertissement

Les journaux côté client peuvent contenir des informations sensibles de votre application. Ne publiez jamais les journaux bruts des applications de production sur des forums publics comme GitHub.

Lorsque vous utilisez le client JavaScript, vous pouvez configurer les options de journalisation à l’aide de la méthode configureLogging sur HubConnectionBuilder :

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

Désactivez la journalisation de l’infrastructure en spécifiant signalR.LogLevel.None dans la configureLogging méthode. Remarquez que certaines journalisations sont envoyées directement par le navigateur et ne peuvent pas être désactivées au moyen de la définition du niveau de journal.

Le tableau suivant présente les niveaux de journalisation disponibles pour le client JavaScript. La définition du niveau de journalisation sur l’une de ces valeurs permet de journaliser à ce niveau et à tous les niveaux au-dessus de celui-ci dans le tableau.

Niveau Descriptif
None Aucun message n’est journalisé.
Critical Messages indiquant un échec dans l’ensemble de l’application.
Error Messages indiquant un échec dans l’opération en cours.
Warning Messages indiquant un problème non fatal.
Information Messages d'information.
Debug Messages de diagnostic utiles pour le débogage.
Trace Messages de diagnostic très détaillés conçus pour diagnostiquer des problèmes spécifiques.

Une fois que vous avez configuré la verbosité, les journaux sont écrits dans la console du navigateur (ou dans la sortie standard dans une application NodeJS).

Si vous souhaitez envoyer des journaux à un système de journalisation personnalisé, vous pouvez fournir un objet JavaScript qui implémente l’interface ILogger. La seule méthode qui doit être implémentée est log, qui prend le niveau de l’événement et du message associé à l’événement. Par exemple :

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

Journalisation du client .NET

Avertissement

Les journaux côté client peuvent contenir des informations sensibles de votre application. Ne publiez jamais les journaux bruts des applications de production sur des forums publics comme GitHub.

Pour obtenir les journaux à partir du client .NET, vous pouvez utiliser la méthode ConfigureLogging sur HubConnectionBuilder. Cela fonctionne de la même façon que la méthode ConfigureLogging sur WebHostBuilder et HostBuilder. Vous pouvez configurer les mêmes fournisseurs de journalisation que vous utilisez dans ASP.NET Core. Toutefois, vous devez installer et activer manuellement les packages NuGet pour les fournisseurs de journalisation individuels.

Pour ajouter la journalisation du client .NET à une application Blazor WebAssembly, consultez la journalisation ASP.NET Core Blazor.

Écriture dans le journal de la console

Pour activer la journalisation de console, ajoutez le package Microsoft.Extensions.Logging.Console. Ensuite, utilisez la méthode AddConsole pour configurer l’enregistreur d’événements de la console :

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

Débogage de journalisation de la fenêtre de sortie

Les journaux d’activité peuvent être configurés pour accéder à la fenêtre Sortie dans Visual Studio. Installez le package Microsoft.Extensions.Logging.Debug et utilisez la méthode AddDebug :

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

Autres fournisseurs de journalisation

SignalR prend en charge d’autres fournisseurs de journalisation comme Serilog, Seq, NLog ou tout autre système de journalisation qui s’intègre à Microsoft.Extensions.Logging. Si votre système de journalisation fournit un ILoggerProvider, vous pouvez l’enregistrer avec AddProvider :

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

Contrôler la verbosité

Lors de l'enregistrement des logs depuis d'autres endroits de l'application, changer le niveau par défaut à Debug peut être trop détaillé. Un filtre peut être utilisé pour configurer le niveau de journalisation des SignalR journaux. Cela peut être effectué avec du code, comme sur le serveur :

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

Traçage dans SignalR

SignalR Le serveur hub et le SignalR client fournissent des informations sur SignalR les connexions et les messages en utilisant DiagnosticSource et Activity. SignalR possède une ActivitySource pour le serveur hub et le client, avaialble à partir de .NET 9.

ActivitySource est un composant utilisé dans le suivi distribué pour créer et gérer des activités (ou des étendues) qui représentent des opérations dans votre application. Ces activités peuvent être utilisées pour :

  • Suivez le flux de requêtes et d’opérations entre différents composants et services.
  • Fournissez des informations précieuses sur les performances et le comportement de votre application.

ActivitySource de serveur SignalR .NET

L’ActivitySource SignalR nommée Microsoft.AspNetCore.SignalR.Server émet des événements pour les appels de méthode hub :

  • Chaque méthode est sa propre activité, de sorte que tout ce qui émet une activité pendant l’appel de méthode hub se trouve sous l’activité de méthode hub.
  • Les activités des méthodes du hub n’ont pas de parent. Cela signifie qu'ils ne sont pas regroupés sous la connexion continue SignalR.

L’exemple suivant utilise le tableau de bord .NET Aspire et les packages OpenTelemetry :

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

Ajoutez le code de démarrage suivant au fichier 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();

L’exemple de sortie suivant provient du tableau de bord Aspire :

Liste d’activités pour les événements d’appel de méthode hub SignalR

ASP.NET Core fournit également ses propres métriques sur Microsoft.AspNetCore.Hosting la source d’événement.

ActivitySource de client SignalR .NET

Le SignalRActivitySource nommé Microsoft.AspNetCore.SignalR.Client émet des événements pour un client SignalR.

  • Les invocations de hub créent une portée client. D’autres SignalR clients, tels que le client JavaScript, ne prennent pas en charge le suivi. Cette fonctionnalité sera ajoutée à davantage de clients dans les prochaines versions.
  • Les appels hub sur le client et le serveur prennent en charge la propagation de contexte. La propagation du contexte de traçage permet un véritable traçage distribué. Il est désormais possible de voir les invocations circuler du client vers le serveur et vice versa.

Voici à quoi ressemblent ces nouvelles activités dans le tableau de bord .NET Aspire :

Traçage distribué SignalR dans le tableau de bord Aspire

Suivis réseau

Avertissement

Une trace du réseau contient le contenu complet de chaque message envoyé par votre application. Ne publiez jamais les traces de réseau brutes des applications de production sur des forums publics comme GitHub.

Si vous rencontrez un problème, une trace réseau peut parfois fournir des informations précieuses. Cela est particulièrement utile lors du dépôt d’un problème sur notre suivi des problèmes.

Collecter une trace de réseau avec Fiddler (option préférée)

Cette méthode fonctionne pour toutes les applications.

Fiddler est un outil puissant de collecte de traces HTTP. Installez-le depuis l’adresse telerik.com/fiddler, lancez-le, puis exécutez votre application et reproduisez le problème. Fiddler est disponible pour Windows et des versions bêta existent pour macOS et Linux.

Si vous vous connectez en utilisant HTTPS, vous devez effectuer quelques étapes supplémentaires pour que Fiddler puisse déchiffrer le trafic HTTPS. Pour plus d’informations, consultez la documentation de Fiddler.

Après avoir collecté la trace, exportez-la en sélectionnant Fichier>Enregistrer>toutes les sessions dans la barre de menus

Exportation de toutes les sessions à partir de Fiddler

Collecter une trace du réseau avec tcpdump (macOS et Linux uniquement)

Cette méthode fonctionne pour toutes les applications.

Les traces TCP brutes peuvent être collectées à l’aide de tcpdump en exécutant la commande suivante à partir d’un interpréteur de commandes. Vous devrez peut-être root ou préfixer la commande avec sudo si vous recevez une erreur d’autorisation :

tcpdump -i [interface] -w trace.pcap

Remplacez [interface] par l’interface réseau sur laquelle vous souhaitez effectuer la capture. En règle générale, il s’agit d’un élément similaire /dev/eth0 (pour une interface Ethernet standard) ou /dev/lo0 (pour le trafic localhost). Pour plus d’informations, consultez la tcpdump page manuelle de votre système hôte.

Collecter une trace du réseau dans le navigateur

Cette méthode fonctionne uniquement pour les applications basées sur un navigateur.

La plupart des consoles d’outils de développement du navigateur ont un onglet « Réseau » qui permet de capturer l’activité réseau entre le navigateur et le serveur. Toutefois, ces traces n’incluent pas les messages WebSocket et d’événements envoyés par le serveur. Lorsque vous utilisez ces transports, l’utilisation d’un outil tel que Fiddler ou TcpDump est une meilleure approche, comme décrit plus loin dans cet article.

Microsoft Edge et Internet Explorer

(Les instructions sont identiques pour Microsoft Edge et Internet Explorer)

  1. Ouvrez les outils de développement en appuyant sur F12
  2. Sélectionnez l’onglet Réseau
  3. Actualisez la page (le cas échéant) et reproduisez le problème.
  4. Sélectionnez l’icône Enregistrer dans la barre d’outils pour exporter la trace en tant que fichier « HAR » :

L’icône Enregistrer dans l’onglet Réseau des outils de développement Microsoft Edge

Google Chrome

  1. Ouvrez les outils de développement en appuyant sur F12
  2. Sélectionnez l’onglet Réseau
  3. Actualisez la page (le cas échéant) et reproduisez le problème.
  4. Cliquez avec le bouton droit n’importe où dans la liste des requêtes, puis choisissez « Enregistrer au format HAR avec le contenu » :

« Enregistrer au format HAR avec le contenu » dans l’onglet Réseau des outils de développement Google Chrome

Mozilla Firefox

  1. Ouvrez les outils de développement en appuyant sur F12
  2. Sélectionnez l’onglet Réseau
  3. Actualisez la page (le cas échéant) et reproduisez le problème.
  4. Cliquez avec le bouton droit n’importe où dans la liste des requêtes, puis choisissez « Tout enregistrer au format HAR »

« Enregistrer au format HAR avec le contenu » dans l’onglet Réseau des outils de développement Mozilla Firefox

Joindre des fichiers diagnostics aux problèmes GitHub

Les fichiers de diagnostic peuvent être attachés aux problèmes GitHub en les renommant afin qu’ils aient une .txt extension, puis en les faisant glisser et en les déplaçant vers le problème.

Remarque

Veuillez ne pas coller le contenu des fichiers journaux ou des traces réseau dans un problème GitHub. Ces journaux et traces peuvent être volumineux et GitHub les tronque généralement.

Faire glisser les fichiers journaux sur le problème GitHub

Métriques

Les métriques sont une représentation des mesures de données sur des intervalles de temps. Par exemple, les requêtes par seconde. Les données de métriques permettent d’observer l’état d’une application à un niveau élevé. Les métriques gRPC .NET sont émises à l’aide de EventCounter.

Métriques de serveur SignalR

Les métriques de serveur SignalR sont signalées sur la source d’événement Microsoft.AspNetCore.Http.Connections.

Nom Descriptif
connections-started Nombre total de connexions démarrées
connections-stopped Nombre total de connexions arrêtées
connections-timed-out Nombre total de connexions expirées
current-connections Connexions en cours
connections-duration Durée moyenne de connexion

Observer les métriques

dotnet-counters est un outil de surveillance des performances pour l’analyse ad hoc de l’intégrité et l’examen des performances de premier niveau. Surveillez une application .NET avec Microsoft.AspNetCore.Http.Connections comme nom de fournisseur. Par exemple :

> 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

Ressources supplémentaires