Journalisation ASP.NET Core Blazor

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version ASP.NET Core 8.0 de cet article.

Cet article explique la journalisation d’application Blazor, notamment la configuration et la façon d’écrire des messages de journal à partir de composants Razor.

Dans cet article, les termes serveur/côté serveur et client/côté client sont utilisés pour distinguer les emplacements où le code d’application s’exécute :

  • Serveur/côté serveur : rendu côté serveur interactif (SSR interactif) d’une application web Blazor.
  • Client/côté client
    • Rendu côté client (CSR) d’une application web Blazor.
    • Application Blazor WebAssembly.

Les exemples de composants de documentation ne configurent généralement pas de mode d’affichage interactif avec une directive @rendermode dans le fichier de définition du composant (.razor) :

  • Dans une application web Blazor, un mode d’affichage interactif doit être appliqué au composant. Ce mode peut être spécifié dans le fichier de définition du composant ou hérité d’un composant parent. Pour plus d’informations, consultez Modes de rendu ASP.NET Core Blazor.

  • Dans une application Blazor WebAssembly autonome, les composants fonctionnent tels qu’ils sont présentés et ne nécessitent pas de mode d’affichage, car ils s’exécutent toujours de manière interactive sur WebAssembly dans une application Blazor WebAssembly.

Lorsque vous utilisez les modes d’affichage WebAssembly interactif ou Auto interactif, le code du composant envoyé au client peut être décompilé et inspecté. N’insérez pas de code privé, de secrets d’application ou d’autres informations personnelles dans les composants du rendu client.

  • Serveur/côté serveur
    • Projet Server d’une application Blazor WebAssembly hébergée.
    • Application Blazor Server.
  • Client/côté client
    • Projet Client d’une application Blazor WebAssembly hébergée.
    • Application Blazor WebAssembly.

Pour obtenir de l’aide sur l’objectif et l’emplacement des fichiers et des dossiers, consultez la structure de projet ASP.NET Core Blazor, qui décrit également l’emplacement du script de démarrage Blazor et l’emplacement des contenus <head> et <body>.

Le meilleur moyen d’exécuter le code de démonstration est de télécharger les exemples d’applications BlazorSample_{PROJECT TYPE} à partir du dépôt GitHub d’exemples Blazor qui correspond à la version de .NET que vous ciblez. Pour le moment, tous les exemples de la documentation ne figurent pas dans les exemples d’applications, mais nous nous employons à transférer la majorité des exemples de l’article .NET 8 dans les exemples d’applications .NET 8. Nous aurons terminé ces transferts dans le courant du premier trimestre 2024.

Configuration

La configuration de la journalisation peut être chargée à partir de fichiers de paramètres d’application. Pour plus d’informations, consultez Configuration d’ASP.NET Core Blazor.

Aux niveaux de journalisation par défaut et sans configuration de fournisseurs de journalisation supplémentaires :

Lorsque l’application est configurée dans le Fichier projet pour utiliser des espaces de noms implicites (<ImplicitUsings>enable</ImplicitUsings>), une directive using pour Microsoft.Extensions.Logging ou toute API de la classe LoggerExtensions n’est pas nécessaire pour prendre en charge les achèvements Visual Studio IntelliSense pour les API ou la génération d’applications. Si les espaces de noms implicites ne sont pas activés, les composants Razor doivent définir explicitement des @usingdirectives pour la journalisation des espaces de noms qui ne sont pas importés via le _Imports.razorfichier.

Niveaux de journal

Les niveaux de journal sont conformes aux niveaux de journal de l’application ASP.NET Core, qui sont répertoriés dans la documentation de l’API à l’adresse LogLevel.

Journalisation des composants Razor

La directive using pour Microsoft.Extensions.Logging est nécessaire pour prendre en charge les achèvements IntelliSense pour les API, telles que LogWarning et LogError.

L’exemple suivant :

  • Injecte un objet ILogger (ILogger<Counter1>) pour créer un enregistreur d'événements. La catégorie du journal est le nom complet du type du composant, Counter.
  • Appelle LogWarning pour journaliser au niveau Warning.

Counter1.razor:

@page "/counter-1"
@inject ILogger<Counter1> Logger

<PageTitle>Counter 1</PageTitle>

<h1>Counter 1</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        Logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-1"
@inject ILogger<Counter1> Logger

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        Logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-1"
@inject ILogger<Counter1> Logger

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        Logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-1"
@using Microsoft.Extensions.Logging
@inject ILogger<Counter1> Logger

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        Logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-1"
@using Microsoft.Extensions.Logging
@inject ILogger<Counter1> Logger

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        Logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}

L’exemple suivant illustre la journalisation avec un composant ILoggerFactory.

Counter2.razor :

@page "/counter-2"
@inject ILoggerFactory LoggerFactory

<PageTitle>Counter 2</PageTitle>

<h1>Counter 2</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        var logger = LoggerFactory.CreateLogger<Counter2>();
        logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-2"
@inject ILoggerFactory LoggerFactory

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        var logger = LoggerFactory.CreateLogger<Counter2>();
        logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-2"
@inject ILoggerFactory LoggerFactory

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        var logger = LoggerFactory.CreateLogger<Counter2>();
        logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-2"
@using Microsoft.Extensions.Logging
@inject ILoggerFactory LoggerFactory

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        var logger = LoggerFactory.CreateLogger<Counter2>();
        logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}
@page "/counter-2"
@using Microsoft.Extensions.Logging
@inject ILoggerFactory LoggerFactory

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        var logger = LoggerFactory.CreateLogger<Counter2>();
        logger.LogWarning("Someone has clicked me!");

        currentCount++;
    }
}

Journalisation côté serveur

Pour obtenir des instructions générales ASP.NET Core de journalisation, consultez Journalisation dans .NET Core et ASP.NET Core.

Journalisation côté client

Toutes les fonctionnalités de la Journalisation ASP.NET Core ne sont pas prises en charge côté client. Par exemple, les composants côté client n'ont pas accès au système de fichiers ou au réseau du client, il n'est donc pas possible d'écrire des journaux sur le stockage physique ou réseau du client. Lorsque vous utilisez un service de journalisation tiers conçu pour fonctionner avec des applications monopages (SPA), suivez les instructions de sécurité du service. Gardez à l’esprit que toutes les données, y compris les clés ou les secrets stockés côté client, ne sont pas sécurisées et peuvent être facilement découvertes par des utilisateurs malveillants.

Selon la version de l’infrastructure et les fonctionnalités de journalisation, les implémentations de journalisation peuvent nécessiter l’ajout de l’espace de noms pour Microsoft.Extensions.Logging au fichier Program :

using Microsoft.Extensions.Logging;

Configurez la journalisation dans les applications côté client avec la propriété WebAssemblyHostBuilder.Logging. La propriété Logging étant de type ILoggingBuilder, les méthodes d’extension de ILoggingBuilder sont prises en charge.

Pour définir le niveau de journalisation minimal, appelez LoggingBuilderExtensions.SetMinimumLevel sur le générateur d’hôte dans le fichier Program avec le LogLevel. L’exemple suivant définit le niveau de journalisation minimal sur Warning :

builder.Logging.SetMinimumLevel(LogLevel.Warning);

Journal dans le fichier Program côté client

La journalisation est prise en charge dans les applications côté client une fois que WebAssemblyHostBuilder est généré à l’aide du fournisseur d’enregistreurs d’événements de console interne de l’infrastructure (WebAssemblyConsoleLoggerProvider (source de référence)).

Dans le fichier Program :

var host = builder.Build();

var logger = host.Services.GetRequiredService<ILoggerFactory>()
    .CreateLogger<Program>();

logger.LogInformation("Logged after the app is built in the Program file.");

await host.RunAsync();

Sortie de la console des outils du développeur :

info: Program[0]
Logged after the app is built in the Program file.

Remarque

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Catégorie de journal côté client

Les catégories de journaux sont prises en charge.

L’exemple suivant montre comment utiliser des catégories de journaux avec le composant Counter d’une application créée à partir d’un modèle de projet Blazor.

Dans la méthode IncrementCount du composant Counter de l’application (Counter.razor) qui injecte un ILoggerFactory en tant que LoggerFactory :

var logger = LoggerFactory.CreateLogger("CustomCategory");
logger.LogWarning("Someone has clicked me!");

Sortie de la console des outils du développeur :

warn: CustomCategory[0]
Someone has clicked me!

ID de l'événement du journal côté client

L’ID d’événement de journal est pris en charge.

L’exemple suivant montre comment utiliser des ID d’événements de journal avec le composant Counter d’une application créée à partir d’un modèle de projet Blazor.

LogEvent.cs :

public class LogEvent
{
    public const int Event1 = 1000;
    public const int Event2 = 1001;
}

Dans la méthode IncrementCount du composant Counter de l’application (Counter.razor) :

logger.LogInformation(LogEvent.Event1, "Someone has clicked me!");
logger.LogWarning(LogEvent.Event2, "Someone has clicked me!");

Sortie de la console des outils du développeur :

info: BlazorSample.Pages.Counter[1000]
Someone has clicked me!
warn: BlazorSample.Pages.Counter[1001]
Someone has clicked me!

Modèle de message de journal côté client

Les modèles de message de journal sont pris en charge :

L’exemple suivant montre comment utiliser des modèles de message de journal avec le composant Counter d’une application créée à partir d’un modèle de projet Blazor.

Dans la méthode IncrementCount du composant Counter de l’application (Counter.razor) :

logger.LogInformation("Someone clicked me at {CurrentDT}!", DateTime.UtcNow);

Sortie de la console des outils du développeur :

info: BlazorSample.Pages.Counter[0]
Someone clicked me at 04/21/2022 12:15:57!

Paramètres d'exception du journal côté client

Les paramètres d’exception de journal sont pris en charge.

L’exemple suivant montre comment utiliser des paramètres d’exception de journal avec le composant Counter d’une application créée à partir d’un modèle de projet Blazor.

Dans la méthode IncrementCount du composant Counter de l’application (Counter.razor) :

currentCount++;

try
{
    if (currentCount == 3)
    {
        currentCount = 4;
        throw new OperationCanceledException("Skip 3");
    }
}
catch (Exception ex)
{
    logger.LogWarning(ex, "Exception (currentCount: {Count})!", currentCount);
}

Sortie de la console des outils du développeur :

warn: BlazorSample.Pages.Counter[0]
Exception (currentCount: 4)!
System.OperationCanceledException: Skip 3
at BlazorSample.Pages.Counter.IncrementCount() in C:UsersAlabaDesktopBlazorSamplePagesCounter.razor:line 28

Fonction de filtre côté client

Les fonctions de filtre sont prises en charge.

L’exemple suivant montre comment utiliser un filtre avec le composant Counter d’une application créée à partir d’un modèle de projet Blazor.

Dans le fichier Program :

builder.Logging.AddFilter((provider, category, logLevel) =>
    category.Equals("CustomCategory2") && logLevel == LogLevel.Information);

Dans la méthode IncrementCount du composant Counter de l’application (Counter.razor) qui injecte un ILoggerFactory en tant que LoggerFactory :

var logger1 = LoggerFactory.CreateLogger("CustomCategory1");
logger1.LogInformation("Someone has clicked me!");

var logger2 = LoggerFactory.CreateLogger("CustomCategory1");
logger2.LogWarning("Someone has clicked me!");

var logger3 = LoggerFactory.CreateLogger("CustomCategory2");
logger3.LogInformation("Someone has clicked me!");

var logger4 = LoggerFactory.CreateLogger("CustomCategory2");
logger4.LogWarning("Someone has clicked me!");

Dans la sortie de la console des outils du développeur, le filtre autorise uniquement la journalisation pour la catégorie CustomCategory2 et le message de niveau journal Information :

info: CustomCategory2[0]
Someone has clicked me!

L’application peut également configurer le filtrage des journaux pour des espaces de noms spécifiques. Par exemple, définissez le niveau de journalisation sur Trace dans le fichier Program :

builder.Logging.SetMinimumLevel(LogLevel.Trace);

Normalement au niveau du journal Trace, la sortie de la console des outils du développeur au niveau Détaillé inclut des messages de journalisation Microsoft.AspNetCore.Components.RenderTree, tels que les suivants :

dbug: Microsoft.AspNetCore.Components.RenderTree.Renderer[3]
Rendering component 14 of type Microsoft.AspNetCore.Components.Web.HeadOutlet

Dans le fichier Program, la journalisation des messages spécifiques à Microsoft.AspNetCore.Components.RenderTree peut être désactivée à l’aide de l’une des approches suivantes :

  • builder.Logging.AddFilter("Microsoft.AspNetCore.Components.RenderTree.*", LogLevel.None);
    
  • builder.Services.PostConfigure<LoggerFilterOptions>(options =>
        options.Rules.Add(
            new LoggerFilterRule(null, 
                                 "Microsoft.AspNetCore.Components.RenderTree.*", 
                                 LogLevel.None, 
                                 null)
        ));
    

Une fois l’un des filtres précédents ajouté à l’application, la sortie de la console au niveau Détaillé n’affiche pas les messages de journalisation de l’API Microsoft.AspNetCore.Components.RenderTree.

Fournisseur d’enregistreurs d’événements personnalisés côté client

L’exemple de cette section illustre un fournisseur d’enregistreurs d’événements personnalisé pour une personnalisation ultérieure.

Ajoutez une référence de package à l’application pour le package Microsoft.Extensions.Logging.Configuration.

Remarque

Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.

Ajoutez la configuration d’enregistreur d’événements personnalisée suivante. La configuration établit un dictionnaire LogLevels qui définit un format de journal personnalisé pour trois niveaux de journalisation : Information, Warning, et Error. Un LogFormatenum est utilisé pour décrire les formats courts (LogFormat.Short) et longs (LogFormat.Long).

CustomLoggerConfiguration.cs :

using Microsoft.Extensions.Logging;

public class CustomLoggerConfiguration
{
    public int EventId { get; set; }

    public Dictionary<LogLevel, LogFormat> LogLevels { get; set; } = 
        new()
        {
            [LogLevel.Information] = LogFormat.Short,
            [LogLevel.Warning] = LogFormat.Short,
            [LogLevel.Error] = LogFormat.Long
        };

    public enum LogFormat
    {
        Short,
        Long
    }
}

Ajoutez l’enregistreur d’événements personnalisé suivant à l’application. Le CustomLogger génère des formats de journal personnalisés en fonction des valeurs logLevel définies dans la configuration précédente CustomLoggerConfiguration.

using Microsoft.Extensions.Logging;
using static CustomLoggerConfiguration;

public sealed class CustomLogger : ILogger
{
    private readonly string name;
    private readonly Func<CustomLoggerConfiguration> getCurrentConfig;

    public CustomLogger(
        string name,
        Func<CustomLoggerConfiguration> getCurrentConfig) =>
        (this.name, this.getCurrentConfig) = (name, getCurrentConfig);

    public IDisposable BeginScope<TState>(TState state) => default!;

    public bool IsEnabled(LogLevel logLevel) =>
        getCurrentConfig().LogLevels.ContainsKey(logLevel);

    public void Log<TState>(
        LogLevel logLevel,
        EventId eventId,
        TState state,
        Exception? exception,
        Func<TState, Exception?, string> formatter)
    {
        if (!IsEnabled(logLevel))
        {
            return;
        }

        CustomLoggerConfiguration config = getCurrentConfig();

        if (config.EventId == 0 || config.EventId == eventId.Id)
        {
            switch (config.LogLevels[logLevel])
            {
                case LogFormat.Short:
                    Console.WriteLine($"{name}: {formatter(state, exception)}");
                    break;
                case LogFormat.Long:
                    Console.WriteLine($"[{eventId.Id, 2}: {logLevel, -12}] {name} - {formatter(state, exception)}");
                    break;
                default:
                    // No-op
                    break;
            }
        }
    }
}

Ajoutez le fournisseur d’enregistreurs d’événements personnalisé suivant à l’application. CustomLoggerProvider adopte une Optionsapproche basée sur pour configurer l’enregistreur d’événements via des fonctionnalités de configuration de journalisation intégrées. Par exemple, l’application peut définir ou modifier les formats de journal via un fichier appsettings.json sans nécessiter de modifications de code pour l’enregistreur d’événements personnalisé, comme illustré à la fin de cette section.

CustomLoggerProvider.cs :

using System.Collections.Concurrent;
using Microsoft.Extensions.Options;

[ProviderAlias("CustomLog")]
public sealed class CustomLoggerProvider : ILoggerProvider
{
    private readonly IDisposable onChangeToken;
    private CustomLoggerConfiguration config;
    private readonly ConcurrentDictionary<string, CustomLogger> loggers =
        new(StringComparer.OrdinalIgnoreCase);

    public CustomLoggerProvider(
        IOptionsMonitor<CustomLoggerConfiguration> config)
    {
        this.config = config.CurrentValue;
        onChangeToken = config.OnChange(updatedConfig => this.config = updatedConfig);
    }

    public ILogger CreateLogger(string categoryName) =>
        loggers.GetOrAdd(categoryName, name => new CustomLogger(name, GetCurrentConfig));

    private CustomLoggerConfiguration GetCurrentConfig() => config;

    public void Dispose()
    {
        loggers.Clear();
        onChangeToken.Dispose();
    }
}

Ajoutez les extensions d’enregistreur d’événements personnalisées suivantes.

CustomLoggerExtensions.cs :

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;

public static class CustomLoggerExtensions
{
    public static ILoggingBuilder AddCustomLogger(
        this ILoggingBuilder builder)
    {
        builder.AddConfiguration();

        builder.Services.TryAddEnumerable(
            ServiceDescriptor.Singleton<ILoggerProvider, CustomLoggerProvider>());

        LoggerProviderOptions.RegisterProviderOptions
            <CustomLoggerConfiguration, CustomLoggerProvider>(builder.Services);

        return builder;
    }
}

Dans le fichier Program sur le générateur d’hôte, effacez le fournisseur existant en appelant ClearProviders et ajoutez le fournisseur de journalisation personnalisé :

builder.Logging.ClearProviders().AddCustomLogger();

Dans le composant CustomLoggerExample suivant :

  • Le message de débogage n’est pas journalisé.
  • Le message d’information est journalisé au format court (LogFormat.Short).
  • Le message d’avertissement est journalisé au format court (LogFormat.Short).
  • Le message d’erreur est journalisé au format long (LogFormat.Long).
  • Le message de trace n’est pas journalisé.

CustomLoggerExample.razor:

@page "/custom-logger-example"
@inject ILogger<CustomLoggerExample> Logger

<p>
    <button @onclick="LogMessages">Log Messages</button>
</p>

@code{
    private void LogMessages()
    {
        Logger.LogDebug(1, "This is a debug message.");
        Logger.LogInformation(3, "This is an information message.");
        Logger.LogWarning(5, "This is a warning message.");
        Logger.LogError(7, "This is an error message.");
        Logger.LogTrace(5!, "This is a trace message.");
    }
}
@page "/custom-logger-example"
@using Microsoft.Extensions.Logging
@inject ILogger<CustomLoggerExample> Logger

<p>
    <button @onclick="LogMessages">Log Messages</button>
</p>

@code{
    private void LogMessages()
    {
        Logger.LogDebug(1, "This is a debug message.");
        Logger.LogInformation(3, "This is an information message.");
        Logger.LogWarning(5, "This is a warning message.");
        Logger.LogError(7, "This is an error message.");
        Logger.LogTrace(5!, "This is a trace message.");
    }
}

La sortie suivante s’affiche dans la console des outils du développeur du navigateur lorsque le bouton Log Messages est sélectionné. Les entrées de journal reflètent les formats appropriés appliqués par l’enregistreur d’événements personnalisé (l’application cliente est nommée LoggingTest) :

LoggingTest.Pages.CustomLoggerExample: This is an information message.
LoggingTest.Pages.CustomLoggerExample: This is a warning message.
[ 7: Error ] LoggingTest.Pages.CustomLoggerExample - This is an error message.

D’après une simple inspection de l’exemple précédent, il est évident que la définition des formats de ligne de journal via le dictionnaire en CustomLoggerConfiguration n’est pas strictement nécessaire. Les formats de ligne appliqués par l’enregistreur d’événements personnalisé (CustomLogger) ont pu être appliqués en vérifiant simplement le logLevel dans la méthode Log. L’objectif de l’affectation du format de journal via la configuration consiste à permettre au développeur de modifier facilement le format du journal via la configuration de l’application, comme le montre l’exemple suivant.

Dans l’application côté client, ajoutez ou mettez à jour le fichier appsettings.json pour inclure la configuration de journalisation. Définissez le format de journal sur Long pour les trois niveaux de journalisation :

{
  "Logging": {
    "CustomLog": {
      "LogLevels": {
        "Information": "Long",
        "Warning": "Long",
        "Error": "Long"
      }
    }
  }
}

Dans l’exemple précédent, notez que l’entrée pour la configuration de l’enregistreur d’événements personnalisé est CustomLog, qui a été appliquée au fournisseur d’enregistreurs d’événements personnalisés (CustomLoggerProvider) en tant qu’alias avec [ProviderAlias("CustomLog")]. La configuration de journalisation aurait pu être appliquée avec le nom CustomLoggerProvider au lieu de CustomLog, mais l’utilisation de l’alias CustomLog est plus conviviale.

Dans le fichier Program, la configuration de la journalisation est consommée. Ajoutez le code suivant :

builder.Logging.AddConfiguration(
    builder.Configuration.GetSection("Logging"));

L’appel à LoggingBuilderConfigurationExtensions.AddConfiguration peut être placé avant ou après l’ajout du fournisseur d’enregistreur d’événements personnalisé.

Réexécutez l’application. Sélectionnez le bouton Log Messages. Notez que la configuration de journalisation est appliquée à partir du fichier appsettings.json. Les trois entrées de journal sont au format long (LogFormat.Long) (l'application cliente est nommée LoggingTest) :

[ 3: Information ] LoggingTest.Pages.CustomLoggerExample - This is an information message.
[ 5: Warning ] LoggingTest.Pages.CustomLoggerExample - This is a warning message.
[ 7: Error ] LoggingTest.Pages.CustomLoggerExample - This is an error message.

Étendue du journal côté client

L’enregistreur d’événements de la console des outils du développeur ne prend pas en charge les étendues de journal. Toutefois, un enregistreur d’événements personnalisé peut prendre en charge les étendues de journal. Pour obtenir un exemple non pris en charge que vous pouvez développer ensuite en fonction de vos besoins, consultez l’exemple d’application BlazorWebAssemblyScopesLogger dans le dépôt GitHub d’exemples Blazor.

L’exemple d’application utilise la syntaxe de journalisation standard ASP.NET Core BeginScope pour indiquer les étendues des messages journalisés. Le service Logger dans l’exemple suivant est un ILogger<CustomLoggerExample>, qui est injecté dans le composant CustomLoggerExample de l’application (CustomLoggerExample.razor).

using (Logger.BeginScope("L1"))
{
    Logger.LogInformation(3, "INFO: ONE scope.");
}

using (Logger.BeginScope("L1"))
{
    using (Logger.BeginScope("L2"))
    {
        Logger.LogInformation(3, "INFO: TWO scopes.");
    }
}

using (Logger.BeginScope("L1"))
{
    using (Logger.BeginScope("L2"))
    {
        using (Logger.BeginScope("L3"))
        {
            Logger.LogInformation(3, "INFO: THREE scopes.");
        }
    }
}

Sortie :

[ 3: Information ] {CLASS} - INFO : UNE étendue. => L1 blazor.webassembly.js:1:35542
[ 3: Information ] {CLASS} - INFO : DEUX étendues. => L1 => L2 blazor.webassembly.js:1:35542
[ 3: Information ] {CLASS} - INFO : TROIS étendues. => L1 => L2 => L3

L’espace réservé {CLASS} dans l’exemple précédent est BlazorWebAssemblyScopesLogger.Pages.CustomLoggerExample.

Journalisation des composants prédéfinis

Les composants prédéfinis exécutent deux fois le code d'initialisation du composant. La journalisation a lieu côté serveur lors de la première exécution du code d’initialisation et côté client lors de la deuxième exécution du code d’initialisation. En fonction de l’objectif de journalisation pendant l’initialisation, la vérification des journaux côté serveur, côté client ou les deux.

La journalisation du client SignalR avec le générateur du client SignalR

Cette section s'applique aux applications côté serveur.

Dans la configuration de démarrage du script Blazor, passez l’objet de configuration configureSignalR qui appelle configureLogging avec le niveau de journal.

Pour la valeur de niveau de journal configureLogging, transmettez l’argument en tant que niveau de journal de chaîne ou entier indiqué dans le tableau suivant.

LogLevel Paramètre de chaîne Paramètre entier
Trace trace 0
Debug debug 1
Information information 2
Warning warning 3
Error error 4
Critical critical 5
None none 6

Exemple 1 : Définissez le niveau de journal Information avec une valeur de chaîne.

Application webBlazor :

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    circuit: {
      configureSignalR: function (builder) {
        builder.configureLogging("information");
      }
    }
  });
</script>

Blazor Server:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureSignalR: function (builder) {
      builder.configureLogging("information");
    }
  });
</script>

Dans l’exemple précédent, l’espace réservé {BLAZOR SCRIPT} est le chemin d’accès de script Blazor et le nom de fichier. Pour connaître l’emplacement du script, consultez ASP.NET Core Blazor structure du projet.

Exemple 2 : Définissez le niveau de journal Information avec une valeur entière.

Application webBlazor :

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    circuit: {
      configureSignalR: function (builder) {
        builder.configureLogging("information");
      }
    }
  });
</script>

Blazor Server :

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureSignalR: function (builder) {
      builder.configureLogging(2);
    }
  });
</script>

Dans l’exemple précédent, l’espace réservé {BLAZOR SCRIPT} est le chemin d’accès de script Blazor et le nom de fichier. Pour connaître l’emplacement du script, consultez ASP.NET Core Blazor structure du projet.

Pour plus d’informations sur le démarrage Blazor (Blazor.start()), consultez Démarrage Blazor d’ASP.NET Core .

La journalisation du client SignalR avec la configuration de l'application

Installez la configuration des paramètres d’application comme décrit dans Configuration Blazor ASP.NET Core. Placez les fichiers de paramètres d’application dans wwwroot qui contiennent un paramètre d’application Logging:LogLevel:HubConnection.

Remarque

En guise d’alternative à l’utilisation des paramètres d’application, vous pouvez passer le LogLevel comme argument à LoggingBuilderExtensions.SetMinimumLevel lorsque la connexion au hub est créée dans un composant Razor. Toutefois, le déploiement accidentel de l’application dans un environnement d’hébergement de production avec une journalisation détaillée peut entraîner une baisse de performances. Nous vous recommandons d’utiliser les paramètres d’application pour définir le niveau de journal.

Fournissez un paramètre d’application Logging:LogLevel:HubConnection dans le fichier par défaut appsettings.json et dans le fichier des paramètres de l’application d’environnement Development. Utilisez un niveau de journal moins détaillé classique pour la valeur par défaut, par exemple LogLevel.Warning. La valeur par défaut des paramètres d’application correspond à ce qui est utilisé dans les environnements Staging et Production si aucun fichier de paramètres d’application pour ces environnements n’est présent. Utilisez un niveau de journal détaillé dans le fichier de paramètres de l’application d’environnement Development, tel que LogLevel.Trace.

wwwroot/appsettings.json :

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "HubConnection": "Warning"
    }
  }
}

wwwroot/appsettings.Development.json :

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "HubConnection": "Trace"
    }
  }
}

Important

La configuration des fichiers de paramètres d’application précédents n’est utilisée par l’application que si les directives de la configuration Blazor d’ASP.NET Core sont respectées.

En haut du fichier de composant Razor (.razor) :

  • Injectez un ILoggerProvider pour ajouter un WebAssemblyConsoleLogger aux fournisseurs de journalisation passés à HubConnectionBuilder. Contrairement à un ConsoleLogger classique, WebAssemblyConsoleLogger est un wrapper autour des API de journalisation spécifiques au navigateur (par exemple, console.log). L’utilisation de WebAssemblyConsoleLogger rend la journalisation possible dans Mono dans un contexte de navigateur.
  • Injectez un IConfiguration pour lire le paramètre d’application Logging:LogLevel:HubConnection.

Remarque

WebAssemblyConsoleLogger est interne et n’est pas pris en charge pour une utilisation directe dans le code du développeur.

@inject ILoggerProvider LoggerProvider
@inject IConfiguration Config

Remarque

L’exemple suivant est basé sur la démonstration dans le SignalR avec le didacticiel Blazor. Pour plus d’informations, consultez le tutoriel.

Dans la OnInitializedAsyncméthode du composant, utilisez HubConnectionBuilderExtensions.ConfigureLogging pour ajouter le fournisseur de journalisation et définir le niveau de journalisation minimal à partir de la configuration :

protected override async Task OnInitializedAsync()
{
    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
        .ConfigureLogging(builder => 
        {
            builder.AddProvider(LoggerProvider);
            builder.SetMinimumLevel(
                Config.GetValue<LogLevel>("Logging:LogLevel:HubConnection"));
        })
        .Build();

    hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...

    await hubConnection.StartAsync();
}

Remarque

Dans l’exemple précédent, Navigation est un NavigationManager injecté.

Pour plus d’informations sur la configuration de l’environnement de l’application, consultez la section Environnements Blazor ASP.NET Core.

Journalisation de l’authentification côté client

Journalisez les messages d’authentification Blazor au niveau de journalisation LogLevel.Debug ou LogLevel.Trace avec une configuration de journalisation dans les paramètres de l’application ou à l’aide d’un filtre de journal pour Microsoft.AspNetCore.Components.WebAssembly.Authentication dans le fichier Program.

Utilisez l’une des approches suivantes :

  • Dans un fichier de paramètres d’application (par exemple, wwwroot/appsettings.Development.json) :

    "Logging": {
      "LogLevel": {
        "Microsoft.AspNetCore.Components.WebAssembly.Authentication": "Debug"
      }
    }
    

    Pour plus d’informations sur la configuration d’une application côté client pour lire les fichiers de paramètres d’application, consultez Configuration Blazor ASP.NET Core.

  • À l’aide d’un filtre de journal, l’exemple suivant :

    • Active la journalisation pour la configuration de build Debug à l’aide d’une directive de préprocesseur C#.
    • Journalise les messages d’authentification Blazor au niveau du journal Debug.
    #if DEBUG
        builder.Logging.AddFilter(
            "Microsoft.AspNetCore.Components.WebAssembly.Authentication", 
            LogLevel.Debug);
    #endif
    

Remarque

Les composants Razor rendus sur le client ne se journalisent que sur la console des outils de développement du navigateur côté client.

Ressources supplémentaires