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 journalise très peu d’informations, mais cela 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"
        }
    }
}

Vous pouvez également configurer cela dans le code de votre 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 niveau Trace produit des diagnostics de très bas niveau et est rarement nécessaire pour diagnostiquer des problèmes dans votre application.

Accéder aux journaux côté serveur

La façon dont vous accédez aux journaux côté serveur dépend de l’environnement dans lequel vous travaillez.

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. Les journaux SignalR 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

Si l’application est déployée dans un autre environnement (par exemple, Docker, Kubernetes ou Windows Service), consultez Journalisation dans .NET Core et ASP.NET Core pour plus d’informations sur la configuration des fournisseurs de journalisation adaptés à l’environnement.

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

Pour désactiver la journalisation de l’infrastructure, spécifiez signalR.LogLevel.None dans la méthode configureLogging. 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.

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

Vous pouvez également configurer les journaux 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é

Si vous vous connectez à partir d’autres emplacements de votre application, il se peut que la modification à Debug du niveau par défaut soit trop verbeuse. Vous pouvez utiliser un filtre pour configurer le niveau de journalisation des journaux d'activité SignalR. 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();

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 de réseau peut parfois fournir beaucoup d’informations pertinentes. Cela est particulièrement utile si vous comptez signaler un problème sur notre outil de 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 très 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 Fiddler.

Une fois que vous avez collecté la trace, vous pouvez l’exporter en choisissant Fichier>Enregistrer>Toutes les sessions dans la barre de menus.

Exporting all sessions from Fiddler

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

Cette méthode fonctionne pour toutes les applications.

Vous pouvez collecter des traces TCP brutes à 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, cela ressemble à /dev/eth0 (pour votre interface Ethernet standard) ou à /dev/lo0 (pour le trafic localhost). Pour plus d’informations, consultez la page man de tcpdump sur 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 des navigateurs possèdent un onglet « Réseau » qui vous 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. Si vous utilisez ces transports, l’utilisation d’un outil comme Fiddler ou TcpDump (décrit ci-dessous) est une meilleure approche.

Microsoft Edge et Internet Explorer

(Les instructions sont les mêmes pour Edge et Internet Explorer)

  1. Appuyez sur F12 pour ouvrir les outils de développement
  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 » :

The Save Icon on the Microsoft Edge Dev Tools Network Tab

Google Chrome

  1. Appuyez sur F12 pour ouvrir les outils de développement
  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 » :

Mozilla Firefox

  1. Appuyez sur F12 pour ouvrir les outils de développement
  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 »

Joindre des fichiers diagnostics aux problèmes GitHub

Vous pouvez joindre des fichiers diagnostics aux problèmes GitHub en les renommant afin qu’ils aient une extension .txt, puis les glisser-déposer sur 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 assez volumineux et GitHub tend à les tronquer.

Dragging log files on to a GitHub issue

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