Compartir vía


Registro de Blazor en ASP.NET Core

Nota

Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulta la versión .NET 8 de este artículo.

Este artículo explica el registro de aplicaciones Blazor, incluida la configuración y cómo escribir mensajes de registro desde los componentes Razor.

Configuración

La configuración de registro se puede cargar desde archivos de configuración de la aplicación. Para obtener más información, consulta Configuración de Blazor en ASP.NET Core.

En los niveles de registro predeterminados y sin configurar proveedores de registro adicionales:

Cuando la aplicación está configurada en el archivo de proyecto para usar espacios de nombres implícitos (<ImplicitUsings>enable</ImplicitUsings>), no se requiere una using directiva para Microsoft.Extensions.Logging ni ninguna API de la clase LoggerExtensions para admitir las finalizaciones o la creación de aplicaciones de Visual Studio de IntelliSense. Si los espacios de nombres implícitos no están habilitados, los componentes de Razor deben definir explícitamente directivas @using para registrar espacios de nombres que no se importan a través del archivo _Imports.razor.

Niveles de registro

Los niveles de registro se ajustan a los niveles de registro de la aplicación ASP.NET Core, que se enumeran en la documentación de la API en LogLevel.

Registro de componente de Razor

La directiva using para Microsoft.Extensions.Logging es necesaria con el fin de permitir las finalizaciones de IntelliSense para las API, como LogWarning y LogError.

En el ejemplo siguiente:

  • Inserta un elemento ILogger (ILogger<Counter1>) para crear un registrador. La categoría del registro es el nombre completo del tipo del componente, Counter.
  • Llama a LogWarning para realizar el registro en el nivel de 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

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

En el siguiente ejemplo se muestra el registro con ILoggerFactory en componentes.

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

Registro del lado servidor

Para obtener información general sobre el registro en ASP.NET Core, consulta Registro en .NET Core y ASP.NET Core.

Registro del lado cliente

No todas las funciones de registro de ASP.NET Core son compatibles con el lado del cliente. Por ejemplo, los componentes del lado del cliente no tienen acceso al sistema de archivos o a la red del cliente, por lo que no es posible escribir registros en el almacenamiento físico o de red del cliente. Al usar un servicio de registro de terceros diseñado para trabajar con aplicaciones de página única (SPA), siga la guía sobre seguridad del servicio. Ten en cuenta que todos los datos, incluidas las claves o secretos almacenados en el lado del cliente, son inseguros y pueden ser descubiertos fácilmente por usuarios malintencionados.

Dependiendo de la versión del framework y de las características de registro, las implementaciones de registro pueden requerir agregar el espacio de nombres para Microsoft.Extensions.Logging al archivo Program:

using Microsoft.Extensions.Logging;

Configura el registro en aplicaciones del lado del cliente con la propiedad WebAssemblyHostBuilder.Logging. La propiedad Logging es de tipo ILoggingBuilder, así que se admiten los métodos de extensión de ILoggingBuilder.

Para establecer el nivel mínimo de registro, llame LoggingBuilderExtensions.SetMinimumLevel al creador del host en el archivo Program con la extensión LogLevel. En el ejemplo siguiente se establece el nivel de registro mínimo en Warning:

builder.Logging.SetMinimumLevel(LogLevel.Warning);

Registro en el archivo del lado del cliente Program

El registro es compatible con aplicaciones del lado del cliente después de que WebAssemblyHostBuilder se crea utilizando el proveedor de registro de la consola interna del marco (WebAssemblyConsoleLoggerProvider (fuente de referencia)).

En el archivo 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();

Salida de la consola de herramientas de desarrollo:

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

Nota:

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, consulta Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Categoría de registro del lado del cliente

Las categorías de registro son admitidas.

En el ejemplo siguiente se muestra cómo usar categorías de registro con el componente Counter de una aplicación creada a partir de una plantilla de proyecto Blazor.

En el método IncrementCount del componente Counter de la aplicación (Counter.razor) que inserta ILoggerFactory como LoggerFactory:

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

Salida de la consola de herramientas de desarrollo:

warn: CustomCategory[0]
Someone has clicked me!

Id. del evento de registro del lado del cliente

Se admite el Id. de evento de registro.

En el ejemplo siguiente se muestra cómo usar identificadores de eventos de registro con el componente Counter de una aplicación creada a partir de una plantilla de proyecto de Blazor.

LogEvent.cs:

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

En el método IncrementCount del componente Counter de la aplicación (Counter.razor):

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

Salida de la consola de herramientas de desarrollo:

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

Plantilla de mensaje de registro del lado del cliente

Se admiten plantillas de mensajes de registro:

En el ejemplo siguiente se muestra cómo usar plantillas de mensaje de registro con el componente Counter de una aplicación creada a partir de una plantilla de proyecto de Blazor.

En el método IncrementCount del componente Counter de la aplicación (Counter.razor):

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

Salida de la consola de herramientas de desarrollo:

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

Parámetros de excepción de registro del lado del cliente

Se admiten parámetros de excepción de registro.

En el ejemplo siguiente se muestra cómo usar parámetros de excepción de registro con el componente Counter de una aplicación creada a partir de una plantilla de proyecto de Blazor.

En el método IncrementCount del componente Counter de la aplicación (Counter.razor):

currentCount++;

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

Salida de la consola de herramientas de desarrollo:

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

Función de filtro del lado del cliente

Se admiten funciones de filtro.

En el ejemplo siguiente se muestra cómo usar un filtro con el componente Counter de una aplicación creada a partir de una plantilla de proyecto de Blazor.

En el archivo Program:

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

En el método IncrementCount del componente Counter de la aplicación (Counter.razor) que inserta ILoggerFactory como 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!");

En la salida de la consola de las herramientas de desarrollo, el filtro solo permite el registro para la categoría CustomCategory2 y el mensaje de nivel de registro Information:

info: CustomCategory2[0]
Someone has clicked me!

La aplicación también puede configurar el filtrado de registros para espacios de nombres específicos. Por ejemplo, establece el nivel de Trace registro en el archivo Program:

builder.Logging.SetMinimumLevel(LogLevel.Trace);

Normalmente, en el nivel de registro Trace, la salida de la consola de las herramientas de desarrollo en el nivel Detallado incluye mensajes de registro de Microsoft.AspNetCore.Components.RenderTree, como los siguientes:

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

En el archivo Program, los mensajes de registro específicos a Microsoft.AspNetCore.Components.RenderTree pueden deshabilitarse utilizando cualquiera de los siguientes métodos:

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

Después de agregar cualquiera de los filtros anteriores a la aplicación, la salida de la consola en el nivel Detallado no muestra los mensajes de registro de la API Microsoft.AspNetCore.Components.RenderTree.

Proveedor de registro personalizado del lado del cliente

En el ejemplo de esta sección se muestra un proveedor de registrador personalizado para obtener una mayor personalización.

Agrega una referencia de paquete a la aplicación para el paquete Microsoft.Extensions.Logging.Configuration.

Nota

Para obtener instrucciones sobre cómo agregar paquetes a aplicaciones .NET, consulta los artículos de Instalación y administración de paquetes en Flujo de trabajo de consumo de paquetes (documentación de NuGet). Confirma las versiones correctas del paquete en NuGet.org.

Agrega la configuración de registrador personalizado siguiente. La configuración establece un diccionario LogLevels que define un formato de registro personalizado para tres niveles de registro: Information, Warning y Error. Se usa un elemento enum deLogFormat para describir formatos cortos (LogFormat.Short) y largos (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
    }
}

Agrega el registrador personalizado siguiente a la aplicación. El elemento CustomLogger genera formatos de registro personalizados en función de los valores logLevel definidos en la configuración CustomLoggerConfiguration anterior.

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

Agrega el proveedor de registrador personalizado siguiente a la aplicación. El elemento CustomLoggerProvider adopta un enfoque basado en Options para configurar el registrador mediante características de configuración de registro integradas. Por ejemplo, la aplicación puede establecer o cambiar los formatos de registro mediante un archivo appsettings.json sin requerir cambios de código en el registrador personalizado, que se muestra al final de esta sección.

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

Agrega las extensiones de registrador personalizado siguientes .

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

En el archivo Program en el constructor de host, borrar el proveedor existente llamando ClearProviders y agregar el proveedor de registro personalizado:

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

En el componente CustomLoggerExample siguiente:

  • El mensaje de depuración no se registra.
  • El mensaje de información se registra en formato corto (LogFormat.Short).
  • El mensaje de advertencia se registra en formato corto (LogFormat.Short).
  • El mensaje de error se registra en formato largo (LogFormat.Long).
  • El mensaje de seguimiento no se registra.

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

En la consola de herramientas de desarrollo del explorador se muestra la salida siguiente cuando se selecciona el botón Log Messages. Las entradas de registro reflejan los formatos apropiados aplicados por el registrador personalizado (la aplicación cliente se llama 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.

A partir de una inspección ocasional del ejemplo anterior, es evidente que no es estrictamente necesario establecer los formatos de línea de registro mediante el diccionario en CustomLoggerConfiguration. Los formatos de línea que aplica el registrador personalizado (CustomLogger) se podrían haber aplicado simplemente comprobando logLevel en el método Log. El propósito de asignar el formato de registro mediante la configuración es que el desarrollador puede cambiar el formato de registro fácilmente por medio de la configuración de la aplicación, tal como se muestra en el ejemplo siguiente.

En la aplicación cliente, agrega o actualiza el archivo appsettings.json para incluir la configuración de registro. Establece el formato de registro en Long para los tres niveles de registro:

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

En el ejemplo anterior, observa que la entrada de la configuración del registrador personalizado es CustomLog, que se aplicó al proveedor de registrador personalizado (CustomLoggerProvider) como un alias con [ProviderAlias("CustomLog")]. La configuración de registro se podría haber aplicado con el nombre CustomLoggerProvider en lugar de CustomLog, pero el uso del alias CustomLog es más intuitivo.

En el archivo Program, consume la configuración de registro. Agrega el código siguiente:

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

La llamada a LoggingBuilderConfigurationExtensions.AddConfiguration se puede realizar antes o después de agregar el proveedor de registrador personalizado.

Ejecuta la aplicación de nuevo. Haz clic en el botón Log Messages. Observa que la configuración de registro se aplica desde el archivo appsettings.json. Las tres entradas de registro están en formato largo (LogFormat.Long) (la aplicación cliente se llama 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.

Ámbitos de registro del lado del cliente

El registrador de consola de las herramientas de desarrollo no admite ámbitos de registro. Sin embargo, un registrador personalizado puede admitir ámbitos de registro. Para ver un ejemplo no compatible que puedes seguir desarrollando para adaptarlo a tus necesidades, consulta la aplicación de ejemplo BlazorWebAssemblyScopesLogger en el repositorio de ejemplos Blazor de GitHub (cómo descargar).

La aplicación de ejemplo usa la sintaxis de registro de ASP.NET Core BeginScope estándar para indicar los ámbitos de los mensajes registrados. El servicio Logger del ejemplo siguiente es de ILogger<CustomLoggerExample>, que se inserta en el componente CustomLoggerExample de la aplicación (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.");
        }
    }
}

Resultado:

[ 3: Información ] {CLASS} - INFO: UN ámbito. => L1 blazor.webassembly.js:1:35542
[ 3: Información ] {CLASS} - INFO: DOS ámbitos. => L1 => L2 blazor.webassembly.js:1:35542
[ 3: Información ] {CLASS} - INFO: TRES ámbitos. => L1 => L2 => L3

El marcador de posición {CLASS} del ejemplo anterior es BlazorWebAssemblyScopesLogger.Pages.CustomLoggerExample.

Registro de componentes representados previamente

Los componentes representados previamente ejecutan el código de inicialización del componente dos veces. El registro tiene lugar en el lado servidor en la primera ejecución del código de inicialización y en el lado cliente en la segunda ejecución del código de inicialización. En función del objetivo de registro durante la inicialización, compruebe los registros en el lado servidor, en el lado cliente o en ambos.

SignalR registro de clientes con el SignalR creador de clientes

Esta sección se aplica a las aplicaciones del lado del servidor.

En la configuración de inicio de script Blazor, pasa el objeto de configuración configureSignalR que llama configureLogging con el nivel de registro.

Para el valor de nivel de registro configureLogging, pasa el argumento como el nivel de registro de cadena o entero que se muestra en la tabla siguiente.

LogLevel Configuración de cadena Configuración de entero
Trace trace 0
Debug debug 1
Information information 2
Warning warning 3
Error error 4
Critical critical 5
None none 6

Ejemplo 1: Establecimiento del nivel de registro de Information con un valor de cadena.

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>

En el ejemplo anterior, el marcador de posición {BLAZOR SCRIPT} es la ruta de acceso del script y el nombre de archivo de Blazor. Para obtener la ubicación del script, consulta la estructura del proyecto ASP.NET CoreBlazor.

Ejemplo 2: Establecimiento del nivel de registro de Information con un valor entero.

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>

En el ejemplo anterior, el marcador de posición {BLAZOR SCRIPT} es la ruta de acceso del script y el nombre de archivo de Blazor. Para obtener la ubicación del script, consulta la estructura del proyecto ASP.NET CoreBlazor.

Nota:

El uso de un entero para especificar el nivel de registro en el ejemplo 2, a menudo denominado número mágico o constante mágica, se considera una práctica de codificación deficiente porque el entero no identifica claramente el nivel de registro al ver el código fuente. Si minimizar los bytes transferidos al explorador es una prioridad, el uso de un entero podría justificarse (considere la posibilidad de quitar el comentario en estos casos).

Para obtener más información sobre el inicio de Blazor (Blazor.start()), consulta Inicio de Blazor en ASP.NET Core.

Registro de clientesSignalR con configuración de aplicaciones

Establece la configuración de los ajustes de la aplicación como se describe en Configuración Blazor de ASP.NET Core. Coloca los archivos de configuración de la aplicación de wwwroot que contengan una configuración de la aplicación Logging:LogLevel:HubConnection.

Nota

Como alternativa al uso de la configuración de la aplicación, puedes pasar LogLevel como argumento para LoggingBuilderExtensions.SetMinimumLevel cuando la conexión del concentrador se cree en un componente Razor. Sin embargo, la implementación accidental de la aplicación en un entorno de hospedaje de producción con registro detallado puede dar lugar a una penalización del rendimiento. Se recomienda usar la configuración de la aplicación para establecer el nivel de registro.

Proporciona una configuración de la aplicación Logging:LogLevel:HubConnection en el archivo appsettings.json predeterminado y en el archivo de configuración de la aplicación de entorno Development. Usa un nivel de registro menos detallado típico para el valor predeterminado, como LogLevel.Warning. El valor de configuración de la aplicación predeterminado es lo que se usa en los entornos Staging y Production si no hay ningún archivo de configuración de la aplicación para esos entornos. Usa un nivel de registro detallado en el archivo de configuración de la aplicación de entorno Development, como 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"
    }
  }
}

Importante

La configuración de los archivos de configuración de la aplicación anteriores solo la usa la aplicación si se siguen las instrucciones de Configuración de Blazor de ASP.NET Core.

En la parte superior del archivo de componente Razor (.razor):

  • Inserta un proveedor ILoggerProvider para agregar un registrador WebAssemblyConsoleLogger a los proveedores de registro pasados a HubConnectionBuilder. A diferencia de los registradores ConsoleLoggerProvider, WebAssemblyConsoleLogger es un contenedor de API de registro específicas de explorador (por ejemplo, console.log). El uso de WebAssemblyConsoleLogger hace posible el registro en Mono dentro de un contexto de explorador.
  • Inserta un elemento IConfiguration para leer la configuración de la aplicación Logging:LogLevel:HubConnection.

Nota

WebAssemblyConsoleLogger es interno y no está disponible para el uso directo en el código de desarrollador.

@inject ILoggerProvider LoggerProvider
@inject IConfiguration Config

Nota

El siguiente ejemplo se basa en la demostración en el SignalR con Blazor el tutorial. Consulta el tutorial para obtener más información.

En el método OnInitializedAsync del componente, usa HubConnectionBuilderExtensions.ConfigureLogging para agregar el proveedor de registro y establecer el nivel de registro mínimo desde la configuración:

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

Nota

En el ejemplo anterior, Navigation es un elemento NavigationManager insertado.

Para obtener más información sobre la configuración del entorno de la aplicación, consulte Entornos de BlazorASP.NET Core.

Registro de autenticación en el lado del cliente

Registre los mensajes de autenticación Blazor en los niveles LogLevel.Debug o de registro LogLevel.Trace con una configuración de registro en los ajustes de la aplicación o utilizando un filtro de registro para Microsoft.AspNetCore.Components.WebAssembly.Authentication en el archivo Program.

Use cualquiera de los procedimientos siguientes:

  • En un archivo de configuración de la aplicación (por ejemplo, wwwroot/appsettings.Development.json):

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

    Para obtener más información sobre cómo configurar una aplicación del lado del cliente para que lea los archivos de configuración de la aplicación, consulte Configuración de ASP.NET Core Blazor.

  • Al usar un filtro de registro, el ejemplo siguiente:

    • Activa el registro de la configuración de compilación de Debug mediante una directiva de preprocesador de C#.
    • Registra los mensajes de autenticación de Blazor en el nivel de registro Debug.
    #if DEBUG
        builder.Logging.AddFilter(
            "Microsoft.AspNetCore.Components.WebAssembly.Authentication", 
            LogLevel.Debug);
    #endif
    

Nota

Las representaciones de componentes Razor en el cliente solo se registran en la consola de herramientas de desarrollo del navegador del lado del cliente.

Recursos adicionales