Freigeben über


ASP.NET Core Blazor-Protokollierung

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

In diesem Artikel wird die Protokollierung in Blazor-Apps erläutert, einschließlich der Konfiguration und des Schreibens von Protokollmeldungen aus Razor-Komponenten.

Konfiguration

Die Protokollierungskonfiguration kann aus App-Einstellungsdateien geladen werden. Weitere Informationen finden Sie unter Konfiguration von Blazor in ASP.NET Core.

Auf standardmäßigen Protokollebenen und ohne Konfiguration zusätzlicher Protokollierungsanbieter gilt Folgendes:

Wenn die App in der Projektdatei für die Verwendung impliziter Namespaces (<ImplicitUsings>enable</ImplicitUsings>) konfiguriert ist, ist weder eine using-Anweisung für Microsoft.Extensions.Logging noch eine API in der Klasse LoggerExtensions erforderlich, um Visual Studio IntelliSense-Vervollständigungen für die API oder die Erstellung von Apps zu unterstützen. Wenn implizite Namespaces nicht aktiviert sind, müssen Razor-Komponenten explizit @using-Anweisungen für Protokollierungsnamespaces definieren, die nicht über die Datei _Imports.razor importiert werden.

Protokolliergrade

Die Protokolliergrade entsprechen den ASP.NET Core-App-Protokolliergraden, die in der API-Dokumentation unter LogLevel aufgeführt sind.

Protokollierung von Razor-Komponenten

Die using-Anweisung für Microsoft.Extensions.Logging ist erforderlich, um die IntelliSense-Vervollständigungen für APIs zu unterstützen, zum Beispiel LogWarning und LogError.

Im Beispiel unten geschieht Folgendes:

  • Es wird ein ILogger-Objekt (ILogger<Counter1>) injiziert, um eine Protokollierung zu erstellen. Die Kategorie des Protokolls ist der vollqualifizierte Name des Komponententyps, also Counter.
  • Es wird LogWarning aufgerufen, um Protokollierung mit dem Protokolliergrad Warning auszuführen.

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

<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++;
    }
}

Im folgenden Beispiel wird die Protokollierung mit ILoggerFactory in Komponenten veranschaulicht.

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

<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++;
    }
}

Serverseitige Protokollierung

Einen allgemeinen Leitfaden zur Protokollierung in ASP.NET Core finden Sie unter Protokollierung in .NET Core und ASP.NET Core.

Clientseitige Protokollierung

Nicht jedes Feature der ASP.NET Core-Protokollierung wird clientseitig unterstützt. Beispielsweise haben clientseitige Komponenten keinen Zugriff auf das Dateisystem oder das Netzwerk des Clients, so dass es nicht möglich ist, Protokolle in den physischen oder Netzwerkspeicher des Clients zu schreiben. Wenn Sie einen Protokollierungsdienst eines Drittanbieters verwenden, der für die Verwendung mit Single-Page-Webanwendungen (SPAs) entwickelt wurde, befolgen Sie die Sicherheitsempfehlungen des Diensts. Beachten Sie, dass alle Daten, einschließlich clientseitig gespeicherter Schlüssel oder Geheimnisse, unsicher sind und von böswilligen Benutzern leicht entdeckt werden können.

Abhängig von der Frameworkversion und den Protokollierungsfeatures kann es für die Implementierung der Protokollierung erforderlich sein, den Namespace für Microsoft.Extensions.Logging in die Datei Program aufzunehmen:

using Microsoft.Extensions.Logging;

Konfigurieren Sie die Protokollierung in clientseitigen-Apps mit der WebAssemblyHostBuilder.Logging-Eigenschaft. Die Logging-Eigenschaft hat den Typ ILoggingBuilder, daher werden die Erweiterungsmethoden von ILoggingBuilder unterstützt.

Um den Mindestprotokolliergrad festzulegen, rufen Sie im Hostbuilder in der Datei Program mit dem LogLevel die Methode LoggingBuilderExtensions.SetMinimumLevel auf. Im folgenden Beispiel wird der Mindestprotokollgrad auf Warning festgelegt:

builder.Logging.SetMinimumLevel(LogLevel.Warning);

Protokollierung in der clientseitigen Program-Datei

Die Protokollierung in clientseitigen Apps wird unterstützt, nachdem der WebAssemblyHostBuilder mit dem internen Konsolenprotokollierungsanbieter des Frameworks (WebAssemblyConsoleLoggerProvider (Referenzquelle)) erstellt wurde.

In der Program-Datei:

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

Ausgabe der Entwicklerstoolskonsole:

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

Hinweis

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Clientseitige Protokollkategorie

Protokollkategorien werden unterstützt.

Das folgende Beispiel zeigt, wie Sie Protokollkategorien mit der Counter-Komponente einer App verwenden, die aus einer Blazor-Projektvorlage erstellt wurde.

In der IncrementCount-Methode der Counter-Komponente der App (Counter.razor), die eine ILoggerFactory als LoggerFactory einfügt:

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

Ausgabe der Entwicklerstoolskonsole:

warn: CustomCategory[0]
Someone has clicked me!

Clientseitige Protokollereignis-ID

Protokollereignis-IDs werden unterstützt.

Das folgende Beispiel zeigt, wie Sie Protokollereignis-IDs mit der Counter-Komponente einer App verwenden, die aus einer Blazor-Projektvorlage erstellt wurde.

LogEvent.cs:

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

In der IncrementCount-Methode der Counter-Komponente der App (Counter.razor):

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

Ausgabe der Entwicklerstoolskonsole:

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

Clientseitige Protokollnachrichtenvorlage

Protokollnachrichtenvorlagen werden unterstützt:

Das folgende Beispiel zeigt, wie Sie Protokollnachrichtenvorlagen mit der Counter-Komponente einer App verwenden, die aus einer Blazor-Projektvorlage erstellt wurde.

In der IncrementCount-Methode der Counter-Komponente der App (Counter.razor):

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

Ausgabe der Entwicklerstoolskonsole:

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

Clientseitige Protokollausnahmeparameter

Protokollausnahmeparameter werden unterstützt.

Das folgende Beispiel zeigt, wie Sie Protokollausnahmeparameter mit der Counter-Komponente einer App verwenden, die aus einer Blazor-Projektvorlage erstellt wurde.

In der IncrementCount-Methode der Counter-Komponente der App (Counter.razor):

currentCount++;

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

Ausgabe der Entwicklerstoolskonsole:

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

Clientseitige Filterfunktion

Filterfunktionen werden unterstützt.

Das folgende Beispiel zeigt, wie Sie einen Filter mit der Counter-Komponente einer App verwenden, die aus einer Blazor-Projektvorlage erstellt wurde.

In der Program-Datei:

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

In der IncrementCount-Methode der Counter-Komponente der App (Counter.razor), die eine ILoggerFactory als LoggerFactory einfügt:

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!");

In der Konsolenausgabe der Entwicklertools ermöglicht der Filter nur die Protokollierung für Meldungen der Kategorie Information und der Protokollebene CustomCategory2:

info: CustomCategory2[0]
Someone has clicked me!

Die App kann auch die Protokollfilterung für bestimmte Namespaces konfigurieren. Legen Sie z. B. den Protokolliergrad in der Program-Datei auf Trace fest:

builder.Logging.SetMinimumLevel(LogLevel.Trace);

Auf der Protokollebene Trace enthält die Konsolenausgabe auf ausführlicher Ebene normalerweise Microsoft.AspNetCore.Components.RenderTree-Protokollierungsnachrichten wie z. B. die folgenden:

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

In der Program-Datei können die für Microsoft.AspNetCore.Components.RenderTree spezifischen Protokollierungsmeldungen anhand einer beliebigen der folgenden Methoden deaktiviert werden:

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

Nachdem der App einer der obigen Filter hinzugefügt wurde, zeigt die Konsolenausgabe auf ausführlicher Ebene keine Protokollierungsnachrichten aus der Microsoft.AspNetCore.Components.RenderTree-API an.

Clientseitiger benutzerdefinierter Protokollierungsanbieter

Das Beispiel in diesem Abschnitt veranschaulicht einen benutzerdefinierten Protokollierungsanbieter zur weiteren Anpassung.

Fügen Sie der App einen Paketverweis für das Paket Microsoft.Extensions.Logging.Configuration hinzu.

Hinweis

Eine Anleitung zum Hinzufügen von Paketen zu .NET-Anwendungen finden Sie in den Artikeln unter Pakete installieren und verwalten unter Workflow für die Paketnutzung (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

Fügen Sie die folgende benutzerdefinierte Protokollierungskonfiguration hinzu. Die Konfiguration richtet ein Wörterbuch LogLevels ein, das ein benutzerdefiniertes Protokollformat für drei Protokolliergrade festlegt: Information, Warning und Error. Mit LogFormat enum werden kurze (LogFormat.Short) und lange (LogFormat.Long) Formate beschrieben.

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

Fügen Sie der App die folgende benutzerdefinierte Protokollierung hinzu. Mit CustomLogger werden benutzerdefinierte Protokollformate basierend auf den logLevel-Werten ausgegeben, die in der vorherigen CustomLoggerConfiguration-Konfiguration definiert wurden.

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

Fügen Sie der App den folgenden benutzerdefinierten Protokollierungsanbieter hinzu. CustomLoggerProvider verwendet einen Options-basierten Ansatz, um die Protokollierung über integrierte Konfigurationsfeatures zu konfigurieren. Beispielsweise kann die App Protokollformate über eine appsettings.json-Datei festlegen oder ändern, ohne dass Codeänderungen an der benutzerdefinierten Protokollierung erforderlich sind. Dies wird am Ende dieses Abschnitts veranschaulicht.

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

Fügen Sie die folgenden benutzerdefinierten Protokollierungserweiterungen hinzu.

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

Löschen Sie in der Program-Datei im Hostbuilder den vorhandenen Anbieter durch einen Aufruf von ClearProviders, und fügen Sie den benutzerdefinierten Protokollierungsanbieter hinzu:

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

In der folgenden CustomLoggerExample-Komponente:

  • Die Debugmeldung wird nicht protokolliert.
  • Die Informationsmeldung wird im Kurzformat (LogFormat.Short) protokolliert.
  • Die Warnmeldung wird im Kurzformat (LogFormat.Short) protokolliert.
  • Die Fehlermeldung wird im Langformat (LogFormat.Long) protokolliert.
  • Die Ablaufverfolgungsmeldung wird nicht protokolliert.

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.");
    }
}

Die folgende Ausgabe wird in der Entwicklungstoolkonsole des Browsers angezeigt, wenn die Log Messages-Schaltfläche ausgewählt ist. Die Protokolleinträge entsprechen den für die benutzerdefinierte Protokollierung verwendeten Formaten (die Client-App hat den Namen 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.

Schon bei einer kurzen Untersuchung des vorherigen Beispiels wird klar, dass es nicht unbedingt erforderlich ist, die Protokollzeilenformate über das Wörterbuch in CustomLoggerConfiguration festzulegen. Die von der benutzerdefinierten Protokollierung (CustomLogger) angewendeten Zeilenformate hätten durch einfaches Überprüfen von logLevel in der Log-Methode angewendet werden können. Der Zweck der Zuweisung des Protokollformats über die Konfiguration besteht darin, dass Entwickler*innen das Protokollformat einfach über die App-Konfiguration ändern können. Dies wird im folgenden Beispiel veranschaulicht.

Fügen Sie in der clientseitigen App die Datei appsettings.json hinzu, oder aktualisieren Sie sie, um die Protokollierungskonfiguration einzuschließen. Legen Sie das Protokollformat für alle drei Protokolliergrade auf Long fest:

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

Beachten Sie im vorherigen Beispiel, dass der Eintrag für die benutzerdefinierte Protokollierungskonfiguration CustomLog lautet, der auf den benutzerdefinierten Protokollierungsanbieter (CustomLoggerProvider) als Alias mit [ProviderAlias("CustomLog")] angewendet wurde. Die Protokollierungskonfiguration hätte mit dem Namen CustomLoggerProvider anstelle von CustomLog angewendet werden können, aber die Verwendung des Alias CustomLog ist benutzerfreundlicher.

Nutzen Sie in der Program-Datei die Protokollierungskonfiguration. Fügen Sie den folgenden Code hinzu:

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

Der Aufruf von LoggingBuilderConfigurationExtensions.AddConfiguration kann entweder vor oder nach dem Hinzufügen des benutzerdefinierten Protokollierungsanbieters eingefügt werden.

Führen Sie die App erneut aus. Wählen Sie die Schaltfläche Log Messages aus. Beachten Sie, dass die Protokollierungskonfiguration von der Datei appsettings.json angewendet wird. Alle drei Protokolleinträge sind im langen (LogFormat.Long) Format angegeben (die Client-App hat den Namen 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.

Clientseitige Protokollbereiche

Die Protokollierung der Entwicklungstoolskonsole unterstützt keine Protokollbereiche. Allerdings kann eine benutzerdefinierte Protokollierung Protokollbereiche unterstützen. Ein nicht unterstütztes Beispiel, das Sie entsprechend Ihren Anforderungen weiterentwickeln können, finden Sie in der BlazorWebAssemblyScopesLogger-Beispiel-App im Blazor-Beispiele-Repository auf GitHub (Downloadanleitung).

Die Beispiel-App verwendet Norm-ASP.NET Core BeginScope Protokollierungssyntax, um Bereiche für protokollierte Nachrichten anzugeben. Der Logger Dienst im folgenden Beispiel ist ein ILogger<CustomLoggerExample>, der in die CustomLoggerExample-Komponente (CustomLoggerExample.razor) der App eingefügt wird.

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.");
        }
    }
}

Ausgabe:

[ 3: Information ] {CLASS} - INFO: ONE scope. => L1 blazor.webassembly.js:1:35542
[ 3: Information ] {CLASS} - INFO: TWO scopes. => L1 => L2 blazor.webassembly.js:1:35542
[ 3: Information ] {CLASS} - INFO: THREE scopes. => L1 => L2 => L3

Der {CLASS}-Platzhalter im vorherigen Beispiel entspricht BlazorWebAssemblyScopesLogger.Pages.CustomLoggerExample.

Protokollierung für vorab gerenderte Komponenten

Vorab gerenderte Komponenten führen Code zur Komponenteninitialisierung zweimal aus. Die Protokollierung erfolgt serverseitig bei der ersten Ausführung des Initialisierungscodes und clientseitig bei der zweiten Ausführung des Initialisierungscodes. Überprüfen Sie je nach Ziel der Protokollierung während der Initialisierung serverseitige, clientseitige oder beide Protokolle.

SignalR-Clientprotokollierung mit dem SignalR-Clientbuilder

Dieser Abschnitt gilt für serverseitige Apps.

Übergeben Sie in der Konfiguration des Blazor-Startskripts das Konfigurationsobjekt configureSignalR, das configureLogging mit dem Protokolliergrad aufruft.

Übergeben Sie für den configureLogging-Wert auf Protokollebene das Argument entweder als Zeichenfolge oder Integerwert auf Protokollebene, wie in der folgenden Tabelle dargestellt.

LogLevel Zeichenfolgeneinstellung Integereinstellung
Trace trace 0
Debug debug 1
Information information 2
Warning warning 3
Error error 4
Critical critical 5
None none 6

Beispiel 1: Festlegen der Information-Protokollebene mit einem Zeichenfolgenwert.

Blazor Web App:

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

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und dem Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Beispiel 2: Festlegen der Information-Protokollebene mit einem Integerwert.

Blazor Web App:

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

Blazor Server:

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

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und dem Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Hinweis

Wenn Sie eine ganze Zahl verwenden, um die Protokollierungsebene in Beispiel 2 anzugeben, die häufig als magische Zahl oder magische Konstante bezeichnet wird, wird als eine schlechte Codierungspraxis betrachtet, da die ganze Zahl beim Anzeigen des Quellcodes die Protokollierungsebene nicht eindeutig identifiziert. Wenn das Minimieren der in den Browser übertragenen Bytes eine Priorität hat, kann die Verwendung einer ganzen Zahl gerechtfertigt sein (ziehen Sie in solchen Fällen in Betracht, den Kommentar zu entfernen).

Weitere Informationen zum Start von Blazor (Blazor.start()) finden Sie unter ASP.NET Core Blazor-Start.

SignalR-Clientprotokollierung mit App-Konfiguration

Konfigurieren Sie die App-Einstellungen wie in ASP.NET Core Blazor-Konfiguration beschrieben. Platzieren Sie App-Einstellungsdateien in wwwroot, die eine Logging:LogLevel:HubConnection-App-Einstellung enthalten.

Hinweis

Alternativ zur Verwendung von App-Einstellungen können Sie LogLevel als Argument an LoggingBuilderExtensions.SetMinimumLevel übergeben, wenn die Hubverbindung in einer Razor-Komponente erstellt wird. Die versehentliche Bereitstellung der App in einer Produktionshostingumgebung mit ausführlicher Protokollierung kann jedoch zu Leistungseinbußen führen. Es wird empfohlen, App-Einstellungen zum Festlegen der Protokollebene zu verwenden.

Geben Sie eine Logging:LogLevel:HubConnection-App-Einstellung in der Standarddatei appsettings.json und in der Development-Umgebungs-App-Einstellungsdatei an. Verwenden Sie eine typische, weniger ausführliche Protokollebene als Standard, z. B. LogLevel.Warning. Der Standardwert für App-Einstellungen wird in Staging- und Production-Umgebungen verwendet, wenn keine App-Einstellungsdateien für diese Umgebungen vorhanden sind. Verwenden Sie eine ausführliche Protokollebene in der Development-Umgebungs-App-Einstellungsdatei, z. B. 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"
    }
  }
}

Wichtig

Die Konfiguration in den vorherigen App-Einstellungsdateien wird von der App nur verwendet, wenn die Anleitung unter ASP.NET Core Blazor-Konfiguration befolgt wird.

Oben in der Razor Komponentendatei (.razor):

  • Fügen Sie eine ILoggerProvider-Instanz ein, um WebAssemblyConsoleLogger zu den an HubConnectionBuilder weitergegebenen Protokollierungsanbietern hinzuzufügen. Anders als bei einem ConsoleLoggerProvider handelt es sich bei WebAssemblyConsoleLogger um einen Wrapper um browserspezifische Protokollierungs-APIs (z. B. console.log). Die Verwendung von WebAssemblyConsoleLogger ermöglicht die Protokollierung in Mono in einem Browserkontext.
  • Fügen Sie IConfiguration zum Lesen der Logging:LogLevel:HubConnection-App-Einstellung ein.

Hinweis

WebAssemblyConsoleLogger ist intern und wird für die direkte Verwendung im Entwicklercode nicht unterstützt.

@inject ILoggerProvider LoggerProvider
@inject IConfiguration Config

Hinweis

Das folgende Beispiel basiert auf der Demonstration im Tutorial Verwenden von SignalR mit Blazor. Weitere Informationen finden Sie im Tutorial.

Verwenden Sie in der OnInitializedAsync-Methode der Komponente HubConnectionBuilderExtensions.ConfigureLogging, um den Protokollierungsanbieter hinzuzufügen und den Mindestprotokolliergrad aus der Konfiguration festzulegen:

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

Hinweis

Im Beispiel oben ist Navigation eine injizierte NavigationManager-Instanz.

Weitere Informationen zum Festlegen der App-Umgebung finden Sie unter ASP.NET Core Blazor-Umgebungen.

Clientseitige Authentifizierungsprotokollierung

Protokollieren Sie Blazor-Authentifizierungsmeldungen mit dem Protokolliergrad LogLevel.Debug oder LogLevel.Trace. Verwenden Sie dazu eine Protokollierungskonfiguration in den App-Einstellungen oder einen Protokollfilter für Microsoft.AspNetCore.Components.WebAssembly.Authentication in der Datei Program.

Verwenden Sie einen der folgenden Ansätze:

  • In einer App-Einstellungsdatei (z. B. wwwroot/appsettings.Development.json):

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

    Weitere Informationen zum Konfigurieren einer clientseitigen App zum Lesen von App-Einstellungsdateien finden Sie unter ASP.NET Core BlazorKonfiguration.

  • Unter Verwendung eines Protokollfilters führt das folgende Beispiel folgende Aktionen aus:

    • Aktivieren der Protokollierung für die Debug-Buildkonfiguration mithilfe einer C#-Präprozessoranweisung
    • Protokollieren von Blazor-Authentifizierungsnachrichten mit dem Protokolliergrad Debug
    #if DEBUG
        builder.Logging.AddFilter(
            "Microsoft.AspNetCore.Components.WebAssembly.Authentication", 
            LogLevel.Debug);
    #endif
    

Hinweis

Für Razor-Komponenten, die auf dem Client gerendert werden, erfolgt die Protokollierung nur an die clientseitige Konsole mit den Browserentwicklertools.

Zusätzliche Ressourcen