Registros en .NET Core y ASP.NET Core

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 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, consulte la versión de .NET 9 de este artículo.

Por Kirk Larkin, Juergen Gutsch y Rick Anderson

En este articulo se describe el registro en .NET tal y como se aplica a las aplicaciones de ASP.NET Core. Para obtener información detallada sobre el registro en .NET, vea Registro en .NET.

Para obtener una guía sobre el registro de Blazor, que se agregue a la guía o la reemplace en este nodo, consulta el registro de Blazor en ASP.NET Core.

Proveedores de registro

Los proveedores de registro almacenan los registros, a excepción del proveedor Console, que los muestra. Por ejemplo, el proveedor de Azure Application Insights almacena los registros en Azure Application Insights. Se pueden habilitar varios proveedores.

Las plantillas de aplic. web predeterminadas de ASP.NET Core llaman a WebApplication.CreateBuilder, que agrega los siguientes proveedores de registro:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

En el código anterior se muestra el archivo Program.cs creado con las plantillas de aplicación web de ASP.NET Core. En las siguientes secciones se proporcionan ejemplos basados en las plantillas de aplicación web de ASP.NET Core.

El código siguiente invalida el conjunto predeterminado de proveedores de registro agregados por WebApplication.CreateBuilder:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Como alternativa, el código de registro anterior se puede escribir de la siguiente manera:

var builder = WebApplication.CreateBuilder();
builder.Host.ConfigureLogging(logging =>
{
    logging.ClearProviders();
    logging.AddConsole();
});

Para otros proveedores, vea:

Creación de registros

Para crear registros, use un objeto ILogger<TCategoryName> desde la inserción de dependencias (DI):

En el ejemplo siguiente:

  • Crea un registrador, ILogger<AboutModel>, que utiliza una categoría de registro del nombre completo del tipo AboutModel. La categoría de registro es una cadena que está asociada con cada registro.
  • Llama a LogInformation para realizar el registro en el nivel de Information. El nivel de registro indica la gravedad del evento registrado.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("About page visited at {DT}", 
            DateTime.UtcNow.ToLongTimeString());
    }
}

Los niveles y las categorías se explican con más detalle posteriormente en este artículo.

Para obtener información sobre Blazor, consulte Registro de Blazor en ASP.NET Core.

registro

La configuración del registro la suele proporcionar la sección Logging de los archivos appsettings.{ENVIRONMENT}.json, donde el marcador de posición {ENVIRONMENT} es el entorno. El siguiente archivo appsettings.Development.json se genera mediante las plantillas de aplicación web de ASP.NET Core:

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

En el código JSON anterior:

  • Se especifican las categorías "Default" y "Microsoft.AspNetCore".
  • La categoría "Microsoft.AspNetCore" se aplica a todas las categorías que comienzan por "Microsoft.AspNetCore". Por ejemplo, esta configuración se aplica a la categoría "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • La categoría "Microsoft.AspNetCore" registra en el nivel de registro Warning y superiores.
  • No se especifica un proveedor de registro específico, por lo que LogLevel se aplica a todos los proveedores de registro habilitados, excepto Windows EventLog.

La propiedad Logging puede tener LogLevel y registrar propiedades del proveedor de registro. LogLevel especifica el nivel mínimo que se va a registrar para las categorías seleccionadas. En el código JSON anterior, se especifican los niveles de registro Information y Warning. LogLevel indica la gravedad del registro y los valores están entre 0 y 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 y None = 6.

Cuando se especifica LogLevel, el registro está habilitado para los mensajes tanto en el nivel especificado como en los superiores. En el código JSON anterior, se registra la categoría Default para Information y los niveles posteriores. Por ejemplo, se registran los mensajes Information, Warning, Error y Critical. Si no se especifica LogLevel, el nivel predeterminado del registro es Information. Para obtener más información, consulte Niveles de registro.

Una propiedad de proveedor puede especificar una propiedad de LogLevel. LogLevel en un proveedor especifica los niveles que se van a registrar para ese proveedor, e invalida la configuración de registro que no es de proveedor. Fíjese en el siguiente archivo appsettings.json :

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

La configuración de Logging.{PROVIDER NAME}.LogLevel anula la configuración de Logging.LogLevel, donde el marcador de posición {PROVIDER NAME} es el nombre del proveedor. En el código JSON anterior, el nivel de registro predeterminado del proveedor Debug se establece en Information:

Logging:Debug:LogLevel:Default:Information

La configuración anterior especifica el nivel de registro Information para cada categoría de Logging:Debug:, excepto Microsoft.Hosting. Cuando se muestra una categoría específica, esa categoría invalida la categoría predeterminada. En el JSON anterior, las categorías de Logging:Debug:LogLevel "Microsoft.Hosting" y "Default" invalidan la configuración de Logging:LogLevel.

Se puede especificar el nivel de registro mínimo para:

  • Proveedores específicos: Por ejemplo, Logging:EventSource:LogLevel:Default:Information.
  • Categorías específicas: Por ejemplo, Logging:LogLevel:Microsoft:Warning.
  • Todos los proveedores y todas las categorías: Logging:LogLevel:Default:Warning

Los registros situados por debajo del nivel mínimo no hacen lo siguiente:

  • no se pasan proveedor;
  • no se registran ni se muestran.

Para suprimir todos los registros, especifique LogLevel.None. LogLevel.None tiene un valor de 6, que es mayor que LogLevel.Critical (5).

Si un proveedor admite ámbitos de registro, IncludeScopes indica si están habilitados. Para obtener más información, consulte Ámbitos de registro.

El siguiente archivo appsettings.json contiene todos los proveedores habilitados de forma predeterminada:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "EventSource": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "EventLog": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "AzureAppServicesFile": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

En el ejemplo anterior:

  • Las categorías y los niveles no son valores sugeridos. El objetivo del ejemplo es mostrar todos los proveedores predeterminados.
  • La configuración de Logging.{PROVIDER NAME}.LogLevel anula la configuración de Logging.LogLevel, donde el marcador de posición {PROVIDER NAME} es el nombre del proveedor. Por ejemplo, el nivel de Debug.LogLevel.Default invalida el nivel de LogLevel.Default.
  • Se usa cada alias de proveedor predeterminado. Cada proveedor define un alias que se puede utilizar en la configuración en lugar del nombre de tipo completo. Los alias de proveedores integrados son los siguientes:
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Registro en Program.cs

En el ejemplo siguiente se llama a Builder.WebApplication.Logger en Program.cs y registra mensajes informativos:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Logger.LogInformation("Adding Routes");
app.MapGet("/", () => "Hello World!");
app.Logger.LogInformation("Starting the app");
app.Run();

En el ejemplo siguiente se llama a AddConsole en Program.cs y se registra el punto de conexión /Test:

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddConsole();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

En el ejemplo siguiente se llama a AddSimpleConsole en Program.cs, se deshabilita la salida de color y se registra el punto de conexión /Test:

using Microsoft.Extensions.Logging.Console;

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(i => i.ColorBehavior = LoggerColorBehavior.Disabled);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

Establecimiento del nivel de registro mediante la línea de comandos, las variables de entorno y otra configuración

El nivel de registro se puede establecer con cualquiera de los proveedores de configuración.

El separador : no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el separador : no es compatible con Bash. El carácter de subrayado doble, __, tiene las siguientes características:

  • Es compatible con todas las plataformas.
  • Se reemplaza automáticamente por dos puntos, :.

Los siguientes comandos:

  • establecen la clave de entorno Logging:LogLevel:Microsoft en un valor de Information en Windows;
  • prueban la configuración cuando use una aplicación creada con las plantillas de aplicación web de ASP.NET Core. El comando dotnet run debe ejecutarse en el directorio del proyecto después de usar set.
set Logging__LogLevel__Microsoft=Information
dotnet run

La configuración del entorno anterior:

  • solo se establece en procesos iniciados desde la ventana de comandos en la que se establecieron;
  • no podrá ser leída por los exploradores que se inician con Visual Studio.

El siguiente comando setx también establece la clave y el valor de entorno en Windows. A diferencia de set, la configuración de setx se conserva. El modificador /M establece la variable en el entorno del sistema. Si no se usa /M, se establece una variable de entorno de usuario.

setx Logging__LogLevel__Microsoft Information /M

Fíjese en el siguiente archivo appsettings.json :

"Logging": {
  "Console": {
    "LogLevel": {
      "Microsoft.Hosting.Lifetime": "Trace"
    }
  }
}

El comando siguiente establece la configuración anterior en el entorno:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Nota:

Al configurar variables de entorno con nombres que contienen . (puntos) en macOS y Linux, considere la posibilidad de "Exportar una variable con un punto (.) en ella" en Stack Exchange y su respuesta aceptada correspondiente.

En Azure App Service, seleccione Nueva configuración de la aplicación en la página Configuración > Configuración. Los ajustes de configuración de Azure App Service:

  • Se cifran en rest y se transmiten a través de un canal cifrado.
  • Se exponen como variables de entorno.

Para más información, consulte el artículo sobre Azure Apps: Invalidación de la configuración de la aplicación con Azure Portal.

Para obtener más información sobre cómo establecer los valores de configuración de ASP.NET Core mediante variables de entorno, vea Variables de entorno. Para obtener información sobre el uso de otros orígenes de configuración, como la línea de comandos, Azure Key Vault, Azure App Configuration, otros formatos de archivo, etc., vea Configuración en ASP.NET Core.

Cómo se aplican las reglas de filtro

Cuando se crea un objeto ILogger<TCategoryName>, el objeto ILoggerFactory selecciona una sola regla por proveedor para aplicar a ese registrador. Todos los mensajes escritos por una instancia ILogger se filtran según las reglas seleccionadas. De las reglas disponibles, se selecciona la más específica para cada par de categoría y proveedor.

Cuando se crea un ILogger para una categoría determinada, se usa el algoritmo siguiente para cada proveedor:

  • Se seleccionan todas las reglas que coinciden con el proveedor o su alias. Si no se encuentra ninguna coincidencia, se seleccionan todas las reglas con un proveedor vacío.
  • Del resultado del paso anterior, se seleccionan las reglas con el prefijo de categoría coincidente más largo. Si no se encuentra ninguna coincidencia, se seleccionan todas las reglas que no especifican una categoría.
  • Si se seleccionan varias reglas, se toma la última.
  • Si no se selecciona ninguna regla, se usa MinimumLevel.

Registro de la salida de dotnet run y Visual Studio

Se muestran los registros creados con los proveedores de registro predeterminados:

  • En Visual Studio
    • En la ventana de salida de Debug al depurar.
    • En la ventana de ASP.NET Core Web Server.
  • En la ventana de la consola cuando la aplicación se ejecuta con dotnet run.

Los registros que comienzan por categorías de "Microsoft" son de .NET. .NET y el código de la aplicación usan la misma API y los mismos proveedores de registro.

Categoría de registro

Cuando se crea un objeto ILogger, se especifica una categoría. Esa categoría se incluye con cada mensaje de registro creado por esa instancia de ILogger. La cadena de categoría es arbitraria, pero la convención es usar el nombre de clase completo. Por ejemplo, en un controlador, el nombre podría ser "TodoApi.Controllers.TodoController". Las aplicaciones web de ASP.NET Core usan ILogger<T> para obtener automáticamente una instancia de ILogger que utiliza el nombre de tipo completo de T como la categoría:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Si se desea una categorización adicional, la convención consiste en usar un nombre jerárquico anexando una subcategoría al nombre de clase completo y especificando explícitamente la categoría mediante ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

La llamada a CreateLogger con un nombre fijo puede ser útil cuando se usa en varios métodos, por lo que los eventos se pueden organizar por categoría.

ILogger<T> es equivale a llamar a CreateLogger con el nombre de tipo completo de T.

Nivel de registro

En la tabla siguiente se enumeran los valores de LogLevel, el método de extensión Log{LogLevel} oportuno y el uso sugerido:

LogLevel Valor Método Descripción
Trace 0 LogTrace Contienen los mensajes más detallados. Estos mensajes pueden contener datos confidenciales de la aplicación. Están deshabilitados de forma predeterminada y no se deben habilitar en un entorno de producción.
Debug 1 LogDebug Para depuración y desarrollo. Debido al elevado volumen, tenga precaución cuando lo use en producción.
Information 2 LogInformation Realiza el seguimiento del flujo general de la aplicación. Puede tener un valor a largo plazo.
Warning 3 LogWarning Para eventos anómalos o inesperados. Normalmente incluye errores o estados que no provocan un error en la aplicación.
Error 4 LogError Para los errores y excepciones que no se pueden controlar. Estos mensajes indican un error en la operación o solicitud actual, no un error de toda la aplicación.
Critical 5 LogCritical Para los errores que requieren atención inmediata. Ejemplos: escenarios de pérdida de datos, espacio en disco insuficiente.
None 6 Especifica que una categoría de registro no debe escribir mensajes.

En la tabla anterior, LogLevel aparece de menor a mayor gravedad.

El primer parámetro del método Log, LogLevel, indica la gravedad del registro. En lugar de llamar a Log(LogLevel, ...), la mayoría de los desarrolladores llaman a los métodos de extensión Log{LOG LEVEL}, donde el marcador de posición {LOG LEVEL} es el nivel de registro. Por ejemplo, las dos llamadas de registro siguientes son funcionalmente equivalentes y generan el mismo registro:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem es el identificador del evento. MyLogEvents forma parte de la aplicación de ejemplo y se muestra en la sección Log event ID (id. de evento de registro).

El paquete NuGet Rick.Docs.Samples.RouteInfo proporciona MyDisplayRouteInfo y ToCtxString. Los métodos muestran la información de ruta de Controller y Razor Page.

El siguiente código crea los registros Information y Warning:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

En el código anterior, el primer parámetro de Log{LOG LEVEL}, MyLogEvents.GetItem, es el identificador de evento de registro. El segundo parámetro es una plantilla de mensaje con marcadores de posición para los valores de argumento proporcionados por el resto de parámetros de método. Los parámetros de método se explican detalladamente en la sección Plantilla de mensaje más adelante en este documento.

Llame al método Log{LOG LEVEL} apropiado para controlar la cantidad de salida de registro que se escribe en un determinado medio de almacenamiento. Por ejemplo:

  • En producción:
    • El registro en los niveles Trace, Debug o Information genera un gran volumen de mensajes de registro detallados. Para controlar los costos y no superar los límites de almacenamiento de datos, registre los mensajes de nivel Trace, Debug o Information en un almacén de datos de alto volumen y bajo costo. Considere la posibilidad de limitar Trace, Debug o Information a categorías específicas.
    • El registro entre los niveles Warning y Critical debe generar pocos mensajes de registro.
      • Los costos y los límites de almacenamiento no suelen ser un problema.
      • Cuantos menos registros haya, mayor será la flexibilidad a la hora de elegir el almacén de datos.
  • En desarrollo:
    • Establézcalo en Warning.
    • Agregue los mensajes Trace, Debug o Information al solucionar problemas. Para limitar la salida, establezca Trace, Debug o Information solo para las categorías que se están investigando.

ASP.NET Core escribe registros de eventos de marco. Por ejemplo, tomemos la salida del registro de:

  • Una aplicación de Razor Pages creada con las plantillas de ASP.NET Core.
  • Registro establecido en Logging:Console:LogLevel:Microsoft:Information.
  • Navegación a la página Privacy:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

El siguiente JSON establece Logging:Console:LogLevel:Microsoft:Information:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

Id. de evento del registro

Cada registro se puede especificar un id. de evento. La aplicación de ejemplo usa la clase MyLogEvents para definir los identificadores de evento:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Un id. de evento asocia un conjunto de eventos. Por ejemplo, todos los registros relacionados con la presentación de una lista de elementos en una página podrían ser 1001.

El proveedor de registro puede almacenar el id. de evento en un campo de identificador, en el mensaje de registro o no almacenarlo. El proveedor de depuración no muestra los identificadores de evento. El proveedor de consola muestra los identificadores de evento entre corchetes después de la categoría:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Algunos proveedores de registro almacenan el identificador de evento en un campo, lo que permite filtrar por el id.

Plantilla de mensaje de registro

Cada API de registro usa una plantilla de mensaje. La plantilla de mensaje puede contener marcadores de posición para los que se proporcionan argumentos. Use los nombres de los marcadores de posición, no números.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

El orden de los parámetros, no sus nombres de marcador de posición, determina qué parámetros se usan para proporcionar valores de marcador de posición en los mensajes de registro. En el código siguiente, los nombres de parámetro están fuera de la secuencia en los marcadores de posición de la plantilla de mensaje:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {Pears}, {Bananas}, {Apples}", apples, pears, bananas);

Sin embargo, los parámetros se asignan a los marcadores de posición en el orden: apples, pears, bananas. El mensaje de registro refleja el orden de los parámetros:

Parameters: 1, 2, 3

Este enfoque permite a los proveedores de registro implementar registro semántico o estructurado. Los propios argumentos se pasan al sistema de registro, no solo a la plantilla de mensaje con formato. Esto permite a los proveedores de registro almacenar los valores de parámetro como campos. Por ejemplo, tomemos el siguiente método de registrador:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Por ejemplo, al registrar en Azure Table Storage:

  • Cada entidad de Azure Table puede tener propiedades ID y RequestTime.
  • Las tablas con propiedades simplifican las consultas en los datos registrados. Por ejemplo, una consulta puede buscar todos los registros dentro de un intervalo RequestTime determinado sin necesidad de analizar el tiempo de espera del mensaje de texto.

Registro de excepciones

Los métodos de registrador tienen sobrecargas que toman un parámetro de excepción:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

El paquete NuGet Rick.Docs.Samples.RouteInfo proporciona MyDisplayRouteInfo y ToCtxString. Los métodos muestran la información de ruta de Controller y Razor Page.

El registro de excepciones es específico del proveedor.

Nivel de registro predeterminado

Si no se establece el nivel de registro predeterminado, su valor será Information.

Por ejemplo, considere la siguiente aplicación web:

  • Creada con las plantillas de aplicación web de ASP.NET.
  • appsettings.json y appsettings.Development.json se eliminaron o se les cambió el nombre.

Con la configuración anterior, al navegar a la página de privacy o home, se generan muchos mensajes de Trace, Debug y Information con Microsoft en el nombre de la categoría.

El código siguiente establece el nivel de registro predeterminado cuando este no se establece en la configuración:

var builder = WebApplication.CreateBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

En general, los niveles de registro se deben especificar en la configuración y no en el código.

Función de filtro

Se invoca una función de filtro para todos los proveedores y las categorías que no tienen reglas asignadas mediante configuración o código:

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter((provider, category, logLevel) =>
{
    if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Controller")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Microsoft")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else
    {
        return false;
    }
});

El código anterior muestra los registros de la consola cuando la categoría contiene Controller o Microsoft y el nivel de registro es Information o superior.

En general, los niveles de registro se deben especificar en la configuración y no en el código.

Categorías de ASP.NET Core

En la tabla siguiente se incluyen algunas categorías usadas por ASP.NET Core.

Category Notas
Microsoft.AspNetCore Diagnósticos generales de ASP.NET Core.
Microsoft.AspNetCore.DataProtection Qué claves se tuvieron en cuenta, encontraron y usaron.
Microsoft.AspNetCore.HostFiltering Hosts permitidos.
Microsoft.AspNetCore.Hosting Cuánto tiempo tardaron en completarse las solicitudes HTTP y a qué hora comenzaron. Qué ensamblados de inicio de hospedaje se cargaron.
Microsoft.AspNetCore.Mvc Diagnósticos de MVC y Razor. Enlace de modelos, ejecución de filtros, compilación de vistas y selección de acciones.
Microsoft.AspNetCore.Routing Información de coincidencia de ruta.
Microsoft.AspNetCore.Server Inicio y detención de conexión y mantener las respuestas activas. Información de certificado HTTPS.
Microsoft.AspNetCore.StaticFiles Archivos servidos.

Para ver más categorías en la ventana de la consola, establezca appsettings.Development.json en lo siguiente:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Para obtener una lista de categorías de Entity Framework, consulte Categorías de mensajes de EF.

Ámbitos de registro

Un ámbito puede agrupar un conjunto de operaciones lógicas. Esta agrupación se puede utilizar para adjuntar los mismos datos para cada registro que se crea como parte de un conjunto. Por ejemplo, cada registro creado como parte del procesamiento de una transacción puede incluir el identificador de dicha transacción.

Un ámbito:

Los siguientes proveedores admiten ámbitos:

Use un ámbito encapsulando las llamadas de registrador en un bloque using:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Proveedores de registro integrados

ASP.NET Core incluye los siguientes proveedores de registro como parte del marco compartido:

Microsoft envía los siguientes proveedores de registro, pero no como parte del marco compartido. Deben instalarse como NuGet adicional.

ASP.NET Core no incluye un proveedor de registro para escribir registros en archivos. Para escribir registros en archivos desde una aplicación ASP.NET Core, considere la posibilidad de usar un proveedor de registro de terceros.

Para obtener información sobre stdout y depurar el registro con el módulo ASP.NET Core, consulte Solución de problemas de ASP.NET Core en Azure App Service e IIS y Módulo ASP.NET Core (ANCM) para IIS.

Consola

El proveedor Console registra la salida en la consola. Para obtener más información sobre cómo ver los registros de Console en desarrollo, consulte Registro de la salida de dotnet run y Visual Studio.

Depuración

El proveedor Debug escribe la salida del registro mediante la clase System.Diagnostics.Debug. Las llamadas a System.Diagnostics.Debug.WriteLine escriben en el proveedor Debug.

En Linux, la ubicación del registro del proveedor Debug depende de la distribución y puede ser una de las siguientes:

  • /var/log/message
  • /var/log/syslog

Origen de eventos

El proveedor EventSource escribe en un origen de eventos multiplataforma con el nombre Microsoft-Extensions-Logging. En Windows, el proveedor utiliza ETW.

herramientas dotnet-trace

La herramienta de dotnet-trace es una herramienta global de CLI multiplataforma que permite la recopilación de seguimientos de .NET Core de un proceso en ejecución. La herramienta recopila datos del proveedor Microsoft.Extensions.Logging.EventSource mediante un LoggingEventSource.

Para conocer las instrucciones de instalación, vea dotnet-trace.

Use la herramienta de dotnet-trace para recopilar un seguimiento de una aplicación:

  1. Ejecute la aplicación con el comando dotnet run.

  2. Determine el identificador del proceso (PID) de la aplicación .NET Core:

    dotnet-trace ps
    

    Busque el PID del proceso que tenga el mismo nombre que el ensamblado de la aplicación.

  3. Ejecute el comando dotnet-trace.

    Sintaxis general del comando:

    dotnet-trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    Al usar un shell de comandos de PowerShell, incluya el valor --providers entre comillas simples ('):

    dotnet-trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    En plataformas que no sean Windows, agregue la opción -f speedscope para cambiar el formato del archivo de seguimiento de salida a speedscope.

    En la tabla siguiente se define la palabra clave:

    Palabra clave Descripción
    1 Registre los eventos meta sobre el elemento LoggingEventSource. No registre eventos de ILogger.
    2 Activa el evento Message cuando se llama a ILogger.Log(). Proporciona la información mediante programación (sin formato).
    4 Activa el evento FormatMessage cuando se llama a ILogger.Log(). Proporciona la versión de cadena con formato de la información.
    8 Activa el evento MessageJson cuando se llama a ILogger.Log(). Proporciona una representación JSON de los argumentos.

    En la tabla siguiente se enumeran los niveles de proveedor:

    Nivel de proveedor Descripción
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    El análisis de un nivel de categoría puede ser una cadena o un número:

    Valor con nombre de categoría Valor numérico
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Nivel de proveedor y nivel de categoría:

    • Están en orden inverso.
    • Las constantes de cadena no son todas idénticas.

    Si no se especifica ningún FilterSpecs, la implementación EventSourceLogger intenta convertir el nivel de proveedor en un nivel de categoría y lo aplica a todas las categorías.

    Nivel de proveedor Nivel de categoría
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Si se proporciona FilterSpecs, cualquier categoría incluida en la lista usa el nivel de categoría codificado allí, todas las demás categorías se filtran.

    En los ejemplos siguientes se da por supuesto:

    • Una aplicación está en ejecución y llamando a logger.LogDebug("12345").
    • El identificador de proceso (PID) se ha establecido a través de set PID=12345, donde 12345 es el PID real.

    Observe el comando siguiente:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    El comando anterior:

    • Captura los mensajes de depuración.
    • No aplica un FilterSpecs.
    • Especifica el nivel 5 que asigna la categoría Depurar.

    Observe el comando siguiente:

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    El comando anterior:

    • No captura mensajes de depuración porque el nivel de categoría 5 es Critical.
    • Proporciona un FilterSpecs.

    El comando siguiente captura los mensajes de depuración porque el nivel de categoría 1 especifica Debug.

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    El comando siguiente captura los mensajes de depuración porque la categoría especifica Debug.

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    Las entradas FilterSpecs de {Logger Category} y {Category Level} representan condiciones de filtrado de registros adicionales. Separe las entradas FilterSpecs con el carácter de punto y coma ;.

    Ejemplo de uso de un shell de comandos de Windows:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    El comando anterior activa lo siguiente:

    • Registrador de origen del evento para generar cadenas con formato (4) de los errores (2).
    • Registro Microsoft.AspNetCore.Hosting en el nivel de registro Informational (4).
  4. Detenga las herramientas dotnet-trace presionando la tecla Entrar o Ctrl+C.

    El seguimiento se guarda con el nombre trace.nettrace en la carpeta en la que se ejecuta el comando dotnet-trace.

  5. Abra el seguimiento con Perfview. Abra el archivo trace.nettrace y explore los eventos de seguimiento.

Si la aplicación no compila el host con WebApplication.CreateBuilder, agregue el proveedor de origen del evento a la configuración de registro de la aplicación.

Para más información, consulte:

Perfview

Use la utilidad PerfView para recopilar y ver los registros. Hay otras herramientas para ver los registros ETW, pero PerfView proporciona la mejor experiencia para trabajar con los eventos ETW emitidos por ASP.NET Core.

Para configurar PerfView para la recopilación de eventos registrados por este proveedor, agregue la cadena *Microsoft-Extensions-Logging a la lista Proveedores adicionales. No olvide el símbolo * al principio de la cadena.

Registro de eventos de Windows

El proveedor EventLog envía la salida del registro al Registro de eventos de Windows. A diferencia de otros proveedores, el proveedor EventLogno hereda la configuración de no proveedor predeterminada. Si no se especifican valores de registro de EventLog, el valor predeterminado será LogLevel.Warning.

Para registrar eventos inferiores a LogLevel.Warning, establezca el nivel de registro de forma explícita. En el ejemplo siguiente se establece el nivel de registro predeterminado del registro de eventos en LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Las sobrecargas AddEventLog pueden pasar en EventLogSettings. Si es null o no se especifica, se usa la siguiente configuración predeterminada:

  • LogName: "Application"
  • SourceName: ".NET Runtime"
  • MachineName: se usa el nombre del equipo local.

En el código siguiente se cambia el valor predeterminado de SourceName (".NET Runtime") por MyLogs:


var builder = WebApplication.CreateBuilder();
builder.Logging.AddEventLog(eventLogSettings =>
{
    eventLogSettings.SourceName = "MyLogs";
});

Azure App Service

El paquete de proveedor Microsoft.Extensions.Logging.AzureAppServices escribe los registros en archivos de texto en el sistema de archivos de una aplicación de Azure App Service y en Blob Storage en una cuenta de Azure Storage.

El paquete del proveedor no se incluye en el marco compartido. Para usar el proveedor, agregue el paquete del proveedor al proyecto.

Para configurar las opciones de proveedor, use AzureFileLoggerOptions y AzureBlobLoggerOptions, tal y como se muestra en el ejemplo siguiente:

using Microsoft.Extensions.Logging.AzureAppServices;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddAzureWebAppDiagnostics();
builder.Services.Configure<AzureFileLoggerOptions>(options =>
{
    options.FileName = "azure-diagnostics-";
    options.FileSizeLimit = 50 * 1024;
    options.RetainedFileCountLimit = 5;
});
builder.Services.Configure<AzureBlobLoggerOptions>(options =>
{
    options.BlobName = "log.txt";
});

Cuando se implementa en Azure App Service, la aplicación usa la configuración de la sección Registros de App Service de la página App Service de Azure Portal. Cuando se actualiza la configuración siguiente, los cambios se aplican de inmediato sin necesidad de reiniciar ni de volver a implementar la aplicación.

  • Registro de la aplicación (sistema de archivos)
  • Registro de la aplicación (blob)

La ubicación predeterminada de los archivos de registro está en la carpeta D:\\home\\LogFiles\\Application y el nombre de archivo predeterminado es diagnostics-yyyymmdd.txt. El límite de tamaño de archivo predeterminado es 10 MB, y el número máximo predeterminado de archivos que se conservan es 2. El nombre predeterminado del blob es {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

El proveedor solo realiza registros cuando el proyecto se ejecuta en el entorno de Azure.

Secuencias de registro de Azure

El streaming de registro de Azure permiten ver la actividad de registro en tiempo real desde:

  • El servidor de aplicaciones
  • El servidor web
  • Error del seguimiento de solicitudes

Para configurar las secuencias de registro de Azure:

  • Desplácese a la página Registros de App Service desde la página del portal de la aplicación.
  • Establezca Registro de la aplicación (sistema de archivos) en Activado.
  • Elija el Nivel de registro. Esta configuración solo se aplica al streaming de registro de Azure.

Desplácese a la página Secuencia de registro para ver los registros. Los mensajes que se registran lo hacen con la interfaz ILogger.

Azure Application Insights

El paquete de proveedor Microsoft.Extensions.Logging.ApplicationInsights escribe registros en Azure Application Insights. Application Insights es un servicio que supervisa una aplicación web y proporciona herramientas para consultar y analizar los datos de telemetría. Si usa este proveedor, puede consultar y analizar los registros mediante las herramientas de Application Insights.

El proveedor de registro se incluye como dependencia de Microsoft.ApplicationInsights.AspNetCore, que es el paquete que proporciona toda la telemetría disponible para ASP.NET Core. Si usa este paquete, no tiene que instalar el proveedor de paquete.

El paquete Microsoft.ApplicationInsights.Web es para ASP.NET 4.x, no ASP.NET Core.

Para obtener más información, vea los siguientes recursos:

Proveedores de registro de terceros

Plataformas de registro de terceros que funcionan con ASP.NET Core:

Algunas plataformas de terceros pueden realizar registro semántico, también conocido como registro estructurado.

El uso de una plataforma de terceros es similar al uso de uno de los proveedores integrados:

  1. Agregue un paquete NuGet al proyecto.
  2. Llame a un método de extensión ILoggerFactory proporcionado por el marco de registro.

Para más información, vea la documentación de cada proveedor. Microsoft no admite los proveedores de registro de terceros.

No hay métodos de registrador asincrónicos

El registro debe ser tan rápido que no merezca la pena el costo de rendimiento del código asincrónico. Si el almacén de datos de registro es lento, no escriba directamente en él. Considere la posibilidad de escribir primero los mensajes de registro en un almacén rápido y, después, moverlos al almacén lento. Por ejemplo, al iniciar sesión en SQL Server, no lo haga directamente en un método Log, ya que los métodos Log son sincrónicos. En su lugar, agregue sincrónicamente mensajes de registro a una cola en memoria y haga que un trabajo en segundo plano extraiga los mensajes de la cola para realizar el trabajo asincrónico de insertar datos en SQL Server. Para obtener más información, vea Instrucciones sobre cómo registrar en una cola de mensajes los almacenes de datos lentos (dotnet/AspNetCore.Docs #11801).

Cambio de los niveles de registro en una aplicación en ejecución

La API de registro no incluye un escenario que permita cambiar los niveles de registro mientras se ejecuta una aplicación. No obstante, algunos proveedores de configuración pueden volver a cargar la configuración, lo que tiene efecto inmediato en la configuración del registro. Por ejemplo, el Proveedor de configuración de archivo vuelve a cargar la configuración de registro de forma predeterminada. Si se cambia la configuración en el código mientras se ejecuta una aplicación, la aplicación puede llamar a IConfigurationRoot.Reload para actualizar la configuración de registro de la aplicación.

ILogger e ILoggerFactory

Las implementaciones y las interfaces de ILogger<TCategoryName> y ILoggerFactory se incluyen en el SDK de .NET Core. También están disponibles en los siguientes paquetes NuGet:

Aplicación de reglas de filtro en el código

El método preferido para establecer las reglas de filtro de registro es mediante la Configuración.

En el siguiente ejemplo se muestra cómo registrar reglas de filtro en el código:

using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Debug;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter("System", LogLevel.Debug);
builder.Logging.AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information);
builder.Logging.AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace);

logging.AddFilter("System", LogLevel.Debug) especifica la categoría System y el nivel de registro Debug. El filtro se aplica a todos los proveedores porque no se ha configurado un proveedor específico.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) especifica:

  • El proveedor de registro Debug.
  • Nivel de registro Information y superiores.
  • Todas las categorías que empiezan con "Microsoft".

Registre automáticamente el ámbito con SpanId, TraceId, ParentId, Baggage y Tags.

Las bibliotecas de registro crean implícitamente un objeto de ámbito con SpanId, TraceId, ParentId,Baggage y Tags. Este comportamiento se configura a través de ActivityTrackingOptions.

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(options =>
{
    options.IncludeScopes = true;
});

builder.Logging.Configure(options =>
{
    options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                       | ActivityTrackingOptions.TraceId
                                       | ActivityTrackingOptions.ParentId
                                       | ActivityTrackingOptions.Baggage
                                       | ActivityTrackingOptions.Tags;
});
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Si se establece el encabezado de solicitud HTTP traceparent, ParentId en el ámbito del registro muestra el W3C parent-id desde el encabezado traceparent enlazado y SpanId en el ámbito de registro muestra el parent-id actualizado para el siguiente paso o intervalo fuera de enlace. Para obtener más información, vea Mutación del campo de seguimiento primario.

Creación de un registrador personalizado

Para obtener más información, consulte Implementación de un proveedor de registro personalizado en .NET.

Recursos adicionales

Por Kirk Larkin, Juergen Gutsch y Rick Anderson

En este tema describe el registro en .NET tal y como se aplica a las aplicaciones de ASP.NET Core. Para obtener información detallada sobre el registro en .NET, vea Registro en .NET. Para obtener más información sobre el registro en aplicaciones Blazor, consulte Registro de Blazor en ASP.NET Core.

Vea o descargue el código de ejemplo (cómo descargarlo).

Proveedores de registro

Los proveedores de registro almacenan los registros, a excepción del proveedor Console, que los muestra. Por ejemplo, el proveedor de Azure Application Insights almacena los registros en Azure Application Insights. Se pueden habilitar varios proveedores.

Las plantillas de aplicación web de ASP.NET Core predeterminadas:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

En el código anterior se muestra la clase Program creada con las plantillas de aplicación web de ASP.NET Core. En las siguientes secciones se proporcionan ejemplos basados en las plantillas de aplicación web de ASP.NET Core, que usan el host genérico. Las aplicaciones de consola que no son de host se explican más adelante en este documento.

Para invalidar el conjunto predeterminado de proveedores de registro agregados por Host.CreateDefaultBuilder, llame a ClearProviders y agregue los proveedores de registro necesarios. Por ejemplo, el código siguiente:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Para otros proveedores, vea:

Creación de registros

Para crear registros, use un objeto ILogger<TCategoryName> desde la inserción de dependencias (DI):

En el ejemplo siguiente:

  • Crea un registrador, ILogger<AboutModel>, que utiliza una categoría de registro del nombre completo del tipo AboutModel. La categoría de registro es una cadena que está asociada con cada registro.
  • Llama a LogInformation para realizar el registro en el nivel de Information. El nivel de registro indica la gravedad del evento registrado.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }
    public string Message { get; set; }

    public void OnGet()
    {
        Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
        _logger.LogInformation(Message);
    }
}

Los niveles y las categorías se explican con más detalle posteriormente en este artículo.

Para obtener información sobre Blazor, consulte Registro de Blazor en ASP.NET Core.

Creación de registros en Main y Startup muestra cómo crear registros en Main y Startup.

registro

La configuración de registros suele proporcionarla la sección Logging de los archivos appsettings.{Environment}.json. El siguiente archivo appsettings.Development.json se genera mediante las plantillas de aplicación web de ASP.NET Core:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

En el código JSON anterior:

  • Se especifican las categorías "Default", "Microsoft" y "Microsoft.Hosting.Lifetime".
  • La categoría "Microsoft" se aplica a todas las categorías que comienzan por "Microsoft". Por ejemplo, esta configuración se aplica a la categoría "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • La categoría "Microsoft" registra en el nivel de registro Warning y superiores.
  • La categoría "Microsoft.Hosting.Lifetime" es más específica que la categoría "Microsoft", por lo que la categoría "Microsoft.Hosting.Lifetime" registra en el nivel de registro "Information" y superiores.
  • No se especifica un proveedor de registro específico, por lo que LogLevel se aplica a todos los proveedores de registro habilitados, excepto Windows EventLog.

La propiedad Logging puede tener LogLevel y registrar propiedades del proveedor de registro. LogLevel especifica el nivel mínimo que se va a registrar para las categorías seleccionadas. En el código JSON anterior, se especifican los niveles de registro Information y Warning. LogLevel indica la gravedad del registro y los valores están entre 0 y 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 y None = 6.

Cuando se especifica LogLevel, el registro está habilitado para los mensajes tanto en el nivel especificado como en los superiores. En el código JSON anterior, se registra la categoría Default para Information y los niveles posteriores. Por ejemplo, se registran los mensajes Information, Warning, Error y Critical. Si no se especifica LogLevel, el nivel predeterminado del registro es Information. Para obtener más información, consulte Niveles de registro.

Una propiedad de proveedor puede especificar una propiedad de LogLevel. LogLevel en un proveedor especifica los niveles que se van a registrar para ese proveedor, e invalida la configuración de registro que no es de proveedor. Fíjese en el siguiente archivo appsettings.json :

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

La configuración de Logging.{providername}.LogLevel invalida la configuración de Logging.LogLevel. En el código JSON anterior, el nivel de registro predeterminado del proveedor Debug se establece en Information:

Logging:Debug:LogLevel:Default:Information

La configuración anterior especifica el nivel de registro Information para cada categoría de Logging:Debug:, excepto Microsoft.Hosting. Cuando se muestra una categoría específica, esa categoría invalida la categoría predeterminada. En el JSON anterior, las categorías de Logging:Debug:LogLevel"Microsoft.Hosting" y "Default" invalidan la configuración de Logging:LogLevel

Se puede especificar el nivel de registro mínimo para:

  • Proveedores específicos: Por ejemplo, Logging:EventSource:LogLevel:Default:Information.
  • Categorías específicas: Por ejemplo, Logging:LogLevel:Microsoft:Warning.
  • Todos los proveedores y todas las categorías: Logging:LogLevel:Default:Warning

Los registros situados por debajo del nivel mínimo no hacen lo siguiente:

  • no se pasan proveedor;
  • no se registran ni se muestran.

Para suprimir todos los registros, especifique LogLevel.None. LogLevel.None tiene un valor de 6, que es mayor que LogLevel.Critical (5).

Si un proveedor admite ámbitos de registro, IncludeScopes indica si están habilitados. Para obtener más información, consulte Ámbitos de registro.

El siguiente archivo appsettings.json contiene todos los proveedores habilitados de forma predeterminada:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "EventSource": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "EventLog": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "AzureAppServicesFile": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

En el ejemplo anterior:

  • Las categorías y los niveles no son valores sugeridos. El objetivo del ejemplo es mostrar todos los proveedores predeterminados.
  • La configuración de Logging.{providername}.LogLevel invalida la configuración de Logging.LogLevel. Por ejemplo, el nivel de Debug.LogLevel.Default invalida el nivel de LogLevel.Default.
  • Se usa cada alias de proveedor predeterminado. Cada proveedor define un alias que se puede utilizar en la configuración en lugar del nombre de tipo completo. Los alias de proveedores integrados son los siguientes:
    • Consola
    • Depurar
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Establecimiento del nivel de registro mediante la línea de comandos, las variables de entorno y otra configuración

El nivel de registro se puede establecer con cualquiera de los proveedores de configuración.

El separador : no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el separador : no es compatible con Bash. El carácter de subrayado doble, __, tiene las siguientes características:

  • Es compatible con todas las plataformas.
  • Se reemplaza automáticamente por dos puntos, :.

Los siguientes comandos:

  • establecen la clave de entorno Logging:LogLevel:Microsoft en un valor de Information en Windows;
  • prueban la configuración cuando use una aplicación creada con las plantillas de aplicación web de ASP.NET Core. El comando dotnet run debe ejecutarse en el directorio del proyecto después de usar set.
set Logging__LogLevel__Microsoft=Information
dotnet run

La configuración del entorno anterior:

  • solo se establece en procesos iniciados desde la ventana de comandos en la que se establecieron;
  • no podrá ser leída por los exploradores que se inician con Visual Studio.

El siguiente comando setx también establece la clave y el valor de entorno en Windows. A diferencia de set, la configuración de setx se conserva. El modificador /M establece la variable en el entorno del sistema. Si no se usa /M, se establece una variable de entorno de usuario.

setx Logging__LogLevel__Microsoft Information /M

Fíjese en el siguiente archivo appsettings.json :

"Logging": {
    "Console": {
      "LogLevel": {
        "Microsoft.Hosting.Lifetime": "Trace"
      }
    }
}

El comando siguiente establece la configuración anterior en el entorno:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

En Azure App Service, seleccione Nueva configuración de la aplicación en la página Configuración > Configuración. Los ajustes de configuración de Azure App Service:

  • Se cifran en rest y se transmiten a través de un canal cifrado.
  • Se exponen como variables de entorno.

Para más información, consulte Aplicaciones de Azure: Invalidación de la configuración de la aplicación mediante Azure Portal.

Para obtener más información sobre cómo establecer los valores de configuración de ASP.NET Core mediante variables de entorno, vea Variables de entorno. Para obtener información sobre el uso de otros orígenes de configuración, como la línea de comandos, Azure Key Vault, Azure App Configuration, otros formatos de archivo, etc., vea Configuración en ASP.NET Core.

Cómo se aplican las reglas de filtro

Cuando se crea un objeto ILogger<TCategoryName>, el objeto ILoggerFactory selecciona una sola regla por proveedor para aplicar a ese registrador. Todos los mensajes escritos por una instancia ILogger se filtran según las reglas seleccionadas. De las reglas disponibles, se selecciona la más específica para cada par de categoría y proveedor.

Cuando se crea un ILogger para una categoría determinada, se usa el algoritmo siguiente para cada proveedor:

  • Se seleccionan todas las reglas que coinciden con el proveedor o su alias. Si no se encuentra ninguna coincidencia, se seleccionan todas las reglas con un proveedor vacío.
  • Del resultado del paso anterior, se seleccionan las reglas con el prefijo de categoría coincidente más largo. Si no se encuentra ninguna coincidencia, se seleccionan todas las reglas que no especifican una categoría.
  • Si se seleccionan varias reglas, se toma la última.
  • Si no se selecciona ninguna regla, se usa MinimumLevel.

Registro de la salida de dotnet run y Visual Studio

Se muestran los registros creados con los proveedores de registro predeterminados:

  • En Visual Studio
    • En la ventana de salida de Debug al depurar.
    • En la ventana de ASP.NET Core Web Server.
  • En la ventana de la consola cuando la aplicación se ejecuta con dotnet run.

Los registros que comienzan por categorías de "Microsoft" pertenecen al código de marco de ASP.NET Core. ASP.NET Core y el código de la aplicación usan la misma API y los mismos proveedores de registro.

Categoría de registro

Cuando se crea un objeto ILogger, se especifica una categoría. Esa categoría se incluye con cada mensaje de registro creado por esa instancia de ILogger. La cadena de categoría es arbitraria, pero la convención es usar el nombre de clase. Por ejemplo, en un controlador, el nombre podría ser "TodoApi.Controllers.TodoController". Las aplicaciones web de ASP.NET Core usan ILogger<T> para obtener automáticamente una instancia de ILogger que utiliza el nombre de tipo completo de T como la categoría:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Para especificar explícitamente la categoría, llame a ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

La llamada a CreateLogger con un nombre fijo puede ser útil cuando se usa en varios métodos, por lo que los eventos se pueden organizar por categoría.

ILogger<T> es equivale a llamar a CreateLogger con el nombre de tipo completo de T.

Nivel de registro

En la tabla siguiente se enumeran los valores de LogLevel, el método de extensión Log{LogLevel} oportuno y el uso sugerido:

LogLevel Valor Método Descripción
Seguimiento 0 LogTrace Contienen los mensajes más detallados. Estos mensajes pueden contener datos confidenciales de la aplicación. Están deshabilitados de forma predeterminada y no se deben habilitar en un entorno de producción.
Depurar 1 LogDebug Para depuración y desarrollo. Debido al elevado volumen, tenga precaución cuando lo use en producción.
Información 2 LogInformation Realiza el seguimiento del flujo general de la aplicación. Puede tener un valor a largo plazo.
Advertencia 3 LogWarning Para eventos anómalos o inesperados. Normalmente incluye errores o estados que no provocan un error en la aplicación.
Error 4 LogError Para los errores y excepciones que no se pueden controlar. Estos mensajes indican un error en la operación o solicitud actual, no un error de toda la aplicación.
Critical) (Crítico) 5 LogCritical Para los errores que requieren atención inmediata. Ejemplos: escenarios de pérdida de datos, espacio en disco insuficiente.
Ninguno 6 Especifica que una categoría de registro no debe escribir ningún mensaje.

En la tabla anterior, LogLevel aparece de menor a mayor gravedad.

El primer parámetro del método Log, LogLevel, indica la gravedad del registro. En lugar de llamar a Log(LogLevel, ...), la mayoría de los desarrolladores llaman a los métodos de extensión Log{LogLevel}. Los métodos de extensión Log{LogLevel}llaman al método Log y especifican el LogLevel. Por ejemplo, las dos llamadas de registro siguientes son funcionalmente equivalentes y generan el mismo registro:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem es el identificador del evento. MyLogEvents forma parte de la aplicación de ejemplo y se muestra en la sección Log event ID (id. de evento de registro).

El paquete NuGet Rick.Docs.Samples.RouteInfo proporciona MyDisplayRouteInfo y ToCtxString. Los métodos muestran la información de ruta de Controller y Razor Page.

El siguiente código crea los registros Information y Warning:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

En el código anterior, el primer parámetro de Log{LogLevel}, MyLogEvents.GetItem, es el identificador de evento de registro. El segundo parámetro es una plantilla de mensaje con marcadores de posición para los valores de argumento proporcionados por el resto de parámetros de método. Los parámetros de método se explican detalladamente en la sección Plantilla de mensaje más adelante en este documento.

Llame al método Log{LogLevel} apropiado para controlar la cantidad de salida de registro que se escribe en un determinado medio de almacenamiento. Por ejemplo:

  • En producción:
    • El registro en los niveles Trace o Information genera un gran volumen de mensajes de registro detallados. Para controlar los costos y no superar los límites de almacenamiento de datos, registre los mensajes de nivel Trace a Information en un almacén de datos de alto volumen y bajo costo. Considere la posibilidad de limitar Trace y Information a categorías específicas.
    • El registro entre los niveles Warning y Critical debe generar pocos mensajes de registro.
      • Los costos y los límites de almacenamiento no suelen ser un problema.
      • Cuantos menos registros haya, mayor será la flexibilidad a la hora de elegir el almacén de datos.
  • En desarrollo:
    • Establézcalo en Warning.
    • Agregue los mensajes Trace oInformation al solucionar problemas. Para limitar la salida, establezca Trace o Information solo para las categorías que se están investigando.

ASP.NET Core escribe registros de eventos de marco. Por ejemplo, tomemos la salida del registro de:

  • Una aplicación de Razor Pages creada con las plantillas de ASP.NET Core.
  • Registro establecido en Logging:Console:LogLevel:Microsoft:Information.
  • Navegación a la página Privacy:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

El siguiente JSON establece Logging:Console:LogLevel:Microsoft:Information:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

Id. de evento del registro

Cada registro se puede especificar un id. de evento. La aplicación de ejemplo usa la clase MyLogEvents para definir los identificadores de evento:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Un id. de evento asocia un conjunto de eventos. Por ejemplo, todos los registros relacionados con la presentación de una lista de elementos en una página podrían ser 1001.

El proveedor de registro puede almacenar el id. de evento en un campo de identificador, en el mensaje de registro o no almacenarlo. El proveedor de depuración no muestra los identificadores de evento. El proveedor de consola muestra los identificadores de evento entre corchetes después de la categoría:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Algunos proveedores de registro almacenan el identificador de evento en un campo, lo que permite filtrar por el id.

Plantilla de mensaje de registro

Cada API de registro usa una plantilla de mensaje. La plantilla de mensaje puede contener marcadores de posición para los que se proporcionan argumentos. Use los nombres de los marcadores de posición, no números.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

El orden de los parámetros, no sus nombres de marcador de posición, determina qué parámetros se usan para proporcionar valores de marcador de posición en los mensajes de registro. En el código siguiente, los nombres de parámetro están fuera de la secuencia en los marcadores de posición de la plantilla de mensaje:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);

Sin embargo, los parámetros se asignan a los marcadores de posición en el orden: apples, pears, bananas. El mensaje de registro refleja el orden de los parámetros:

Parameters: 1, 2, 3

Este enfoque permite a los proveedores de registro implementar registro semántico o estructurado. Los propios argumentos se pasan al sistema de registro, no solo a la plantilla de mensaje con formato. Esto permite a los proveedores de registro almacenar los valores de parámetro como campos. Por ejemplo, tomemos el siguiente método de registrador:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Por ejemplo, al registrar en Azure Table Storage:

  • Cada entidad de Azure Table puede tener propiedades ID y RequestTime.
  • Las tablas con propiedades simplifican las consultas en los datos registrados. Por ejemplo, una consulta puede buscar todos los registros dentro de un intervalo RequestTime determinado sin necesidad de analizar el tiempo de espera del mensaje de texto.

Registro de excepciones

Los métodos de registrador tienen sobrecargas que toman un parámetro de excepción:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

El paquete NuGet Rick.Docs.Samples.RouteInfo proporciona MyDisplayRouteInfo y ToCtxString. Los métodos muestran la información de ruta de Controller y Razor Page.

El registro de excepciones es específico del proveedor.

Nivel de registro predeterminado

Si no se establece el nivel de registro predeterminado, su valor será Information.

Por ejemplo, considere la siguiente aplicación web:

  • Creada con las plantillas de aplicación web de ASP.NET.
  • appsettings.json y appsettings.Development.json se eliminaron o se les cambió el nombre.

Con la configuración anterior, al navegar a la página de privacy o home, se generan muchos mensajes de Trace, Debug y Information con Microsoft en el nombre de la categoría.

El código siguiente establece el nivel de registro predeterminado cuando este no se establece en la configuración:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

En general, los niveles de registro se deben especificar en la configuración y no en el código.

Función de filtro

Se invoca una función de filtro para todos los proveedores y las categorías que no tienen reglas asignadas mediante configuración o código:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddFilter((provider, category, logLevel) =>
                {
                    if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Controller")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Microsoft")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

El código anterior muestra los registros de la consola cuando la categoría contiene Controller o Microsoft y el nivel de registro es Information o superior.

En general, los niveles de registro se deben especificar en la configuración y no en el código.

Categorías EF Core y ASP.NET Core

La tabla siguiente conti9ene algunas categorías usadas por ASP.NET Core y Entity Framework Core, con notas sobre los registros:

Categoría Notas
Microsoft.AspNetCore Diagnósticos generales de ASP.NET Core.
Microsoft.AspNetCore.DataProtection Qué claves se tuvieron en cuenta, encontraron y usaron.
Microsoft.AspNetCore.HostFiltering Hosts permitidos.
Microsoft.AspNetCore.Hosting Cuánto tiempo tardaron en completarse las solicitudes HTTP y a qué hora comenzaron. Qué ensamblados de inicio de hospedaje se cargaron.
Microsoft.AspNetCore.Mvc Diagnósticos de MVC y Razor. Enlace de modelos, ejecución de filtros, compilación de vistas y selección de acciones.
Microsoft.AspNetCore.Routing Información de coincidencia de ruta.
Microsoft.AspNetCore.Server Inicio y detención de conexión y mantener las respuestas activas. Información de certificado HTTPS.
Microsoft.AspNetCore.StaticFiles Archivos servidos.
Microsoft.EntityFrameworkCore Diagnósticos generales de Entity Framework Core. Actividad y la configuración de bases de datos, detección de cambios y migraciones.

Para ver más categorías en la ventana de la consola, establezca appsettings.Development.json en lo siguiente:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Ámbitos de registro

Un ámbito puede agrupar un conjunto de operaciones lógicas. Esta agrupación se puede utilizar para adjuntar los mismos datos para cada registro que se crea como parte de un conjunto. Por ejemplo, cada registro creado como parte del procesamiento de una transacción puede incluir el identificador de dicha transacción.

Un ámbito:

Los siguientes proveedores admiten ámbitos:

Use un ámbito encapsulando las llamadas de registrador en un bloque using:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Proveedores de registro integrados

ASP.NET Core incluye los siguientes proveedores de registro como parte del marco compartido:

Microsoft envía los siguientes proveedores de registro, pero no como parte del marco compartido. Deben instalarse como NuGet adicional.

ASP.NET Core no incluye un proveedor de registro para escribir registros en archivos. Para escribir registros en archivos desde una aplicación ASP.NET Core, considere la posibilidad de usar un proveedor de registro de terceros.

Para obtener información sobre stdout y depurar el registro con el módulo ASP.NET Core, consulte Solución de problemas de ASP.NET Core en Azure App Service e IIS y Módulo ASP.NET Core (ANCM) para IIS.

Consola

El proveedor Console registra la salida en la consola. Para obtener más información sobre cómo ver los registros de Console en desarrollo, consulte Registro de la salida de dotnet run y Visual Studio.

Depuración

El proveedor Debug escribe la salida del registro mediante la clase System.Diagnostics.Debug. Las llamadas a System.Diagnostics.Debug.WriteLine escriben en el proveedor Debug.

En Linux, la ubicación del registro del proveedor Debug depende de la distribución y puede ser una de las siguientes:

  • /var/log/message
  • /var/log/syslog

Origen de eventos

El proveedor EventSource escribe en un origen de eventos multiplataforma con el nombre Microsoft-Extensions-Logging. En Windows, el proveedor utiliza ETW.

herramienta de seguimiento de dotnet

La herramienta de seguimiento de dotnet es una herramienta global de CLI multiplataforma que permite la recopilación de seguimientos de .NET Core de un proceso en ejecución. La herramienta recopila datos del proveedor Microsoft.Extensions.Logging.EventSource mediante un LoggingEventSource.

Vea dotnet-trace para obtener instrucciones de instalación.

Use la herramienta de seguimiento de dotnet para recopilar un seguimiento de una aplicación:

  1. Ejecute la aplicación con el comando dotnet run.

  2. Determine el identificador del proceso (PID) de la aplicación .NET Core:

    dotnet trace ps
    

    Busque el PID del proceso que tenga el mismo nombre que el ensamblado de la aplicación.

  3. Ejecute el comando dotnet trace.

    Sintaxis general del comando:

    dotnet trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    Al usar un shell de comandos de PowerShell, incluya el valor --providers entre comillas simples ('):

    dotnet trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    En plataformas que no sean Windows, agregue la opción -f speedscope para cambiar el formato del archivo de seguimiento de salida a speedscope.

    En la tabla siguiente se define la palabra clave:

    Palabra clave Descripción
    1 Registre los eventos meta sobre el elemento LoggingEventSource. No registre eventos de ILogger.
    2 Activa el evento Message cuando se llama a ILogger.Log(). Proporciona la información mediante programación (sin formato).
    4 Activa el evento FormatMessage cuando se llama a ILogger.Log(). Proporciona la versión de cadena con formato de la información.
    8 Activa el evento MessageJson cuando se llama a ILogger.Log(). Proporciona una representación JSON de los argumentos.

    En la tabla siguiente se enumeran los niveles de proveedor:

    Nivel de proveedor Descripción
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    El análisis de un nivel de categoría puede ser una cadena o un número:

    Valor con nombre de categoría Valor numérico
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Nivel de proveedor y nivel de categoría:

    • Están en orden inverso.
    • Las constantes de cadena no son todas idénticas.

    Si no se especifica ningún FilterSpecs, la implementación EventSourceLogger intenta convertir el nivel de proveedor en un nivel de categoría y lo aplica a todas las categorías.

    Nivel de proveedor Nivel de categoría
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Si se proporciona FilterSpecs, cualquier categoría incluida en la lista usa el nivel de categoría codificado allí, todas las demás categorías se filtran.

    En los ejemplos siguientes se da por supuesto:

    • Una aplicación está en ejecución y llamando a logger.LogDebug("12345").
    • El identificador de proceso (PID) se ha establecido a través de set PID=12345, donde 12345 es el PID real.

    Observe el comando siguiente:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    El comando anterior:

    • Captura los mensajes de depuración.
    • No aplica un FilterSpecs.
    • Especifica el nivel 5 que asigna la categoría Depurar.

    Observe el comando siguiente:

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    El comando anterior:

    • No captura mensajes de depuración porque el nivel de categoría 5 es Critical.
    • Proporciona un FilterSpecs.

    El comando siguiente captura los mensajes de depuración porque el nivel de categoría 1 especifica Debug.

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    El comando siguiente captura los mensajes de depuración porque la categoría especifica Debug.

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    Las entradas FilterSpecs de {Logger Category} y {Category Level} representan condiciones de filtrado de registros adicionales. Separe las entradas FilterSpecs con el carácter de punto y coma ;.

    Ejemplo de uso de un shell de comandos de Windows:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    El comando anterior activa lo siguiente:

    • Registrador de origen del evento para generar cadenas con formato (4) de los errores (2).
    • Registro Microsoft.AspNetCore.Hosting en el nivel de registro Informational (4).
  4. Presione la tecla Entrar o Ctrl + C para detener las herramientas de seguimiento de dotnet.

    El seguimiento se guarda con el nombre trace.nettrace en la carpeta en la que se ejecuta el comando dotnet trace.

  5. Abra el seguimiento con Perfview. Abra el archivo trace.nettrace y explore los eventos de seguimiento.

Si la aplicación no compila el host con CreateDefaultBuilder, agregue el proveedor de origen del evento a la configuración de registro de la aplicación.

Para obtener más información, consulte:

Perfview

Use la utilidad PerfView para recopilar y ver los registros. Hay otras herramientas para ver los registros ETW, pero PerfView proporciona la mejor experiencia para trabajar con los eventos ETW emitidos por ASP.NET Core.

Para configurar PerfView para la recopilación de eventos registrados por este proveedor, agregue la cadena *Microsoft-Extensions-Logging a la lista Proveedores adicionales. No olvide el símbolo * al principio de la cadena.

Registro de eventos de Windows

El proveedor EventLog envía la salida del registro al Registro de eventos de Windows. A diferencia de otros proveedores, el proveedor EventLogno hereda la configuración de no proveedor predeterminada. Si no se especifican valores de registro de EventLog, el valor predeterminado será LogLevel.Warning.

Para registrar eventos inferiores a LogLevel.Warning, establezca el nivel de registro de forma explícita. En el ejemplo siguiente se establece el nivel de registro predeterminado del registro de eventos en LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Las sobrecargas de AddEventLog pueden pasar EventLogSettings. Si es null o no se especifica, se usa la siguiente configuración predeterminada:

  • LogName: "Application"
  • SourceName: ".NET Runtime"
  • MachineName: se usa el nombre del equipo local.

En el código siguiente se cambia el valor predeterminado de SourceName (".NET Runtime") por MyLogs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddEventLog(eventLogSettings =>
                {
                    eventLogSettings.SourceName = "MyLogs"; 
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Azure App Service

El paquete de proveedor Microsoft.Extensions.Logging.AzureAppServices escribe los registros en archivos de texto en el sistema de archivos de una aplicación de Azure App Service y en Blob Storage en una cuenta de Azure Storage.

El paquete del proveedor no se incluye en el marco compartido. Para usar el proveedor, agregue el paquete del proveedor al proyecto.

Para configurar las opciones de proveedor, use AzureFileLoggerOptions y AzureBlobLoggerOptions, tal y como se muestra en el ejemplo siguiente:

public class Scopes
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
                .ConfigureServices(serviceCollection => serviceCollection
                    .Configure<AzureFileLoggerOptions>(options =>
                    {
                        options.FileName = "azure-diagnostics-";
                        options.FileSizeLimit = 50 * 1024;
                        options.RetainedFileCountLimit = 5;
                    })
                    .Configure<AzureBlobLoggerOptions>(options =>
                    {
                        options.BlobName = "log.txt";
                    }))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Cuando se implementa en Azure App Service, la aplicación usa la configuración de la sección Registros de App Service de la página App Service de Azure Portal. Cuando se actualiza la configuración siguiente, los cambios se aplican de inmediato sin necesidad de reiniciar ni de volver a implementar la aplicación.

  • Registro de la aplicación (sistema de archivos)
  • Registro de la aplicación (blob)

La ubicación predeterminada de los archivos de registro es la carpeta D:\home\LogFiles\Application y el nombre de archivo predeterminado es diagnostics-yyyymmdd.txt. El límite de tamaño de archivo predeterminado es 10 MB, y el número máximo predeterminado de archivos que se conservan es 2. El nombre de blob predeterminado es {nombre-de-la-aplicación}{marca de tiempo}/aaaa/mm/dd/hh/{guid}-applicationLog.txt.

El proveedor solo realiza registros cuando el proyecto se ejecuta en el entorno de Azure.

Secuencias de registro de Azure

El streaming de registro de Azure permiten ver la actividad de registro en tiempo real desde:

  • El servidor de aplicaciones
  • El servidor web
  • Error del seguimiento de solicitudes

Para configurar las secuencias de registro de Azure:

  • Desplácese a la página Registros de App Service desde la página del portal de la aplicación.
  • Establezca Registro de la aplicación (sistema de archivos) en Activado.
  • Elija el Nivel de registro. Esta configuración solo se aplica al streaming de registro de Azure.

Desplácese a la página Secuencia de registro para ver los registros. Los mensajes que se registran lo hacen con la interfaz ILogger.

Azure Application Insights

El paquete de proveedor Microsoft.Extensions.Logging.ApplicationInsights escribe los registros en Azure Application Insights. Application Insights es un servicio que supervisa una aplicación web y proporciona herramientas para consultar y analizar los datos de telemetría. Si usa este proveedor, puede consultar y analizar los registros mediante las herramientas de Application Insights.

El proveedor de registro se incluye como dependencia de Microsoft.ApplicationInsights.AspNetCore, que es el paquete que proporciona toda la telemetría disponible para ASP.NET Core. Si usa este paquete, no tiene que instalar el proveedor de paquete.

El paquete Microsoft.ApplicationInsights.Web es para ASP.NET 4.x, no para ASP.NET Core.

Para obtener más información, vea los siguientes recursos:

Proveedores de registro de terceros

Plataformas de registro de terceros que funcionan con ASP.NET Core:

Algunas plataformas de terceros pueden realizar registro semántico, también conocido como registro estructurado.

El uso de una plataforma de terceros es similar al uso de uno de los proveedores integrados:

  1. Agregue un paquete NuGet al proyecto.
  2. Llame a un método de extensión ILoggerFactory proporcionado por el marco de registro.

Para más información, vea la documentación de cada proveedor. Microsoft no admite los proveedores de registro de terceros.

Aplicación de consola que no es de host

Para ver un ejemplo de cómo usar el host genérico en una aplicación de consola que no sea web, vea el archivo Program.cs de la aplicación de ejemplo de tareas en segundo plano (Tareas en segundo plano con servicios hospedados en ASP.NET Core).

El código de registro para las aplicaciones sin un host genérico es distinto en la forma en que se agregan los proveedores y se crean los registradores.

Proveedores de registro

En una aplicación de consola que no sea de host, llame al método de extensión Add{provider name} del proveedor al crear un elemento LoggerFactory:

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Creación de registros

Para crear registros, use un objeto de ILogger<TCategoryName>. Use LoggerFactory para crear ILogger.

En el ejemplo siguiente, se crea un registrador con LoggingConsoleApp.Program como la categoría.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

En el ejemplo siguiente, el registrador se usa para crear registros con nivel de Information. El nivel de registro indica la gravedad del evento registrado.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Los niveles y las categorías se explican con más detalle en este documento.

Registro durante la construcción del host

No se admite directamente el registro durante la construcción del host. Sin embargo, se puede usar un registrador independiente. En el ejemplo siguiente, se usa un registrador Serilog para registrarse en CreateHostBuilder. AddSerilog usa la configuración estática especificada en Log.Logger:

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builtConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddCommandLine(args)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.File(builtConfig["Logging:FilePath"])
            .CreateLogger();

        try
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddRazorPages();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {   
                    logging.AddSerilog();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

Configuración de un servicio que dependa de ILogger

La inserción del constructor de un registrador en Startup funciona en versiones anteriores de ASP.NET Core, ya que se crea un contenedor de inserción de dependencias independiente para el host de web. Para conocer por qué solo se crea un contenedor para el host genérico, vea el anuncio de cambios importantes.

Para configurar un servicio que dependa de ILogger<T>, use la inserción de constructores o proporcione un método Factory. Usar un Factory Method es la opción recomendada si no tiene otra alternativa. Por ejemplo, tomemos un servicio que necesita una instancia de ILogger<T> proporcionada por DI:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddRazorPages();

    services.AddSingleton<IMyService>((container) =>
    {
        var logger = container.GetRequiredService<ILogger<MyService>>();
        return new MyService() { Logger = logger };
    });
}

El código resaltado anterior es un elemento Func<T,TResult> que se ejecuta la primera vez que el contenedor de inserción de dependencias necesita crear una instancia de MyService. Puede acceder a cualquiera de los servicios registrados de esta forma.

Creación de registros en Main

El código siguiente registra en Main mediante la obtención de una instancia de ILogger de inserción de dependencias después de compilar el host:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Host created.");

    host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Creación de registros durante el inicio

El código siguiente escribe registros en Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
                      ILogger<Startup> logger)
{
    if (env.IsDevelopment())
    {
        logger.LogInformation("In Development.");
        app.UseDeveloperExceptionPage();
    }
    else
    {
        logger.LogInformation("Not Development.");
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapRazorPages();
    });
}

No se admite la escritura de registros antes de la finalización del contenedor de inserción de dependencias configurado en el método Startup.ConfigureServices:

  • No se admite la inyección del registrador en el constructor Startup.
  • No se admite la inyección del registrador en la signatura del método Startup.ConfigureServices.

El motivo de esta restricción es que los registros dependen de la inserción de dependencias y de la configuración, que a su vez depende de la inserción de dependencias. El contenedor de inserción de dependencias no se configura hasta que finaliza ConfigureServices.

Para obtener información sobre la configuración de un servicio que depende de ILogger<T> o sobre el motivo de que la inserción de constructor de un registrador en Startup funcionase en versiones anteriores, vea Configuración de un servicio que depende de ILogger

No hay métodos de registrador asincrónicos

El registro debe ser tan rápido que no merezca la pena el costo de rendimiento del código asincrónico. Si el almacén de datos de registro es lento, no escriba directamente en él. Considere la posibilidad de escribir primero los mensajes de registro en un almacén rápido y, después, moverlos al almacén lento. Por ejemplo, al iniciar sesión en SQL Server, no lo haga directamente en un método Log, ya que los métodos Log son sincrónicos. En su lugar, agregue sincrónicamente mensajes de registro a una cola en memoria y haga que un trabajo en segundo plano extraiga los mensajes de la cola para realizar el trabajo asincrónico de insertar datos en SQL Server. Para obtener más información, vea este problema de GitHub.

Cambio de los niveles de registro en una aplicación en ejecución

La API de registro no incluye un escenario que permita cambiar los niveles de registro mientras se ejecuta una aplicación. No obstante, algunos proveedores de configuración pueden volver a cargar la configuración, lo que tiene efecto inmediato en la configuración del registro. Por ejemplo, el Proveedor de configuración de archivo vuelve a cargar la configuración de registro de forma predeterminada. Si se cambia la configuración en el código mientras se ejecuta una aplicación, la aplicación puede llamar a IConfigurationRoot.Reload para actualizar la configuración de registro de la aplicación.

ILogger e ILoggerFactory

Las implementaciones y las interfaces de ILogger<TCategoryName> y ILoggerFactory se incluyen en el SDK de .NET Core. También están disponibles en los siguientes paquetes NuGet:

Aplicación de reglas de filtro en el código

El método preferido para establecer las reglas de filtro de registro es mediante la Configuración.

En el siguiente ejemplo se muestra cómo registrar reglas de filtro en el código:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
               logging.AddFilter("System", LogLevel.Debug)
                  .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
                  .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

logging.AddFilter("System", LogLevel.Debug) especifica la categoría System y el nivel de registro Debug. El filtro se aplica a todos los proveedores porque no se ha configurado un proveedor específico.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) especifica:

  • El proveedor de registro Debug.
  • Nivel de registro Information y superiores.
  • Todas las categorías que empiezan con "Microsoft".

Registro automático del ámbito con SpanId, TraceId y ParentId

Las bibliotecas de registro crean implícitamente un objeto de ámbito con SpanId, TraceId y ParentId. Este comportamiento se configura a través de ActivityTrackingOptions.

  var loggerFactory = LoggerFactory.Create(logging =>
  {
      logging.Configure(options =>
      {
          options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                              | ActivityTrackingOptions.TraceId
                                              | ActivityTrackingOptions.ParentId;
      }).AddSimpleConsole(options =>
      {
          options.IncludeScopes = true;
      });
  });

Si se establece el encabezado de solicitud HTTP traceparent, ParentId en el ámbito del registro muestra el W3C parent-id desde el encabezado traceparent enlazado y SpanId en el ámbito de registro muestra el parent-id actualizado para el siguiente paso o intervalo fuera de enlace. Para obtener más información, vea Mutación del campo de seguimiento primario.

Creación de un registrador personalizado

Para obtener más información, consulte Implementación de un proveedor de registro personalizado en .NET.

Recursos adicionales