Registros en .NET Core y ASP.NET Core
Por Kirk Larkin, Juergen Gutsch y Rick Anderson
.NET Core es compatible con una API de registro que funciona con una gran variedad de proveedores de registro integrados y de terceros. En este artículo se muestra cómo usar las API de registro con proveedores integrados.
La mayoría de los ejemplos de código que se muestran en este artículo son de aplicaciones de ASP.NET Core. Las partes específicas de registro de estos fragmentos de código son válidas para cualquier aplicación de .NET Core que use el host genérico. Las plantillas de aplicación Web de ASP.NET Core usan el host genérico.
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:
- usan el host genérico;
- llaman a CreateDefaultBuilder, que agrega los siguientes proveedores de registro:
- Consola
- Depurar
- EventSource
- EventLog: Solo Windows
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:
- Llama a ClearProviders para quitar todas las instancias de ILoggerProvider del generador.
- Agrega el proveedor de registro Console.
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 tipoAboutModel. 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 Creación de registros en Blazor y Blazor WebAssembly en este documento.
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 registroWarningy 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
LogLevelse 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 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}.LogLevelinvalida la configuración deLogging.LogLevel. Por ejemplo, el nivel deDebug.LogLevel.Defaultinvalida el nivel deLogLevel.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
- Depuración
- 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. __, el carácter de subrayado doble, tiene las siguientes características:
- Es compatible con todas las plataformas. Por ejemplo, el separador
:no es compatible con Bash, pero__sí. - Se reemplaza automáticamente por un signo
:.
Los siguientes comandos:
- establecen la clave de entorno
Logging:LogLevel:Microsoften un valor deInformationen 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 rundebe ejecutarse en el directorio del proyecto después de usarset.
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
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 reposo 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("MyCategory");
}
public void OnGet()
{
_logger.LogInformation("GET Pages.ContactModel called.");
}
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.
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
TraceoInformationgenera 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 nivelTraceaInformationen un almacén de datos de alto volumen y bajo costo. Considere la posibilidad de limitarTraceyInformationa categorías específicas. - El registro entre los niveles
WarningyCriticaldebe 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.
- El registro en los niveles
- En desarrollo:
- Establézcalo en
Warning. - Agregue los mensajes
TraceoInformational solucionar problemas. Para limitar la salida, establezcaTraceoInformationsolo para las categorías que se están investigando.
- Establézcalo en
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 (privacidad):
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 marcadores de posición, no sus nombres, determina qué parámetros se usan para proporcionar sus valores. En el código siguiente, los nombres de parámetro están fuera de la secuencia en la plantilla de mensaje:
string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);
El código anterior crea un mensaje de registro con los valores de parámetro en secuencia:
Parameter values: param1, param2
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
IDyRequestTime. - Las tablas con propiedades simplifican las consultas en los datos registrados. Por ejemplo, una consulta puede buscar todos los registros dentro de un intervalo
RequestTimedeterminado 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.
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 eliminados o con el nombre cambiado.
Con la configuración anterior, al navegar a la página de privacidad o de inicio, 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 ASP.NET Core y EF 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:
- es un tipo IDisposable devuelto por el método BeginScope;
- se mantiene hasta que se elimina.
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;
using (_logger.BeginScope("using block message"))
{
_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);
}
El JSON siguiente habilita ámbitos para el proveedor de la consola:
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true, // Required to use Scopes.
"LogLevel": {
"Microsoft": "Warning",
"Default": "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}
}
El código siguiente permite ámbitos para el proveedor de la consola:
En general, el registro se debe especificar en la configuración y no en el código.
Proveedores de registro integrados
ASP.NET Core incluye los siguientes proveedores de registro:
- Consola
- Depurar
- EventSource
- EventLog
- AzureAppServicesFile y AzureAppServicesBlob
- ApplicationInsights
Para obtener información sobre stdout y el registro de depuración 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.
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:
Ejecute la aplicación con el comando
dotnet run.Determine el identificador del proceso (PID) de la aplicación .NET Core:
- En Windows, siga uno de estos procedimientos:
- Administrador de tareas (Ctrl + Alt + Supr)
- Comando TaskList
- Comando de PowerShell Get-Process
- En Linux, use el comando pidof.
Busque el PID del proceso que tenga el mismo nombre que el ensamblado de la aplicación.
- En Windows, siga uno de estos procedimientos:
Ejecute el comando
dotnet trace.Sintaxis general del comando:
dotnet trace collect -p {PID} --providers Microsoft-Extensions-Logging:{Keyword}:{Event Level} :FilterSpecs=\" {Logger Category 1}:{Event Level 1}; {Logger Category 2}:{Event Level 2}; ... {Logger Category N}:{Event Level N}\"Al usar un shell de comandos de PowerShell, incluya el valor
--providersentre comillas simples ('):dotnet trace collect -p {PID} --providers 'Microsoft-Extensions-Logging:{Keyword}:{Event Level} :FilterSpecs=\" {Logger Category 1}:{Event Level 1}; {Logger Category 2}:{Event Level 2}; ... {Logger Category N}:{Event Level N}\"'En plataformas que no sean Windows, agregue la opción
-f speedscopepara cambiar el formato del archivo de seguimiento de salida aspeedscope.Palabra clave Descripción 1 Registre los eventos meta sobre el elemento LoggingEventSource. No registre eventos deILogger).2 Activa el evento Messagecuando se llama aILogger.Log(). Proporciona la información mediante programación (sin formato).4 Activa el evento FormatMessagecuando se llama aILogger.Log(). Proporciona la versión de cadena con formato de la información.8 Activa el evento MessageJsoncuando se llama aILogger.Log(). Proporciona una representación JSON de los argumentos.Nivel de evento Descripción 0 LogAlways1 Critical2 Error3 Warning4 Informational5 VerboseLas entradas
FilterSpecsde{Logger Category}y{Event Level}representan condiciones de filtrado de registros adicionales. Separe las entradasFilterSpecscon un punto y coma (;).Ejemplo de uso de un shell de comandos de Windows (no hay comillas simples alrededor del valor
--providers):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.Hostingen el nivel de registroInformational(4).
- Registrador de origen del evento para generar cadenas con formato (
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.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:
- Seguimiento de la utilidad de análisis de rendimiento (dotnet-trace) (documentación de .NET Core)
- Seguimiento de la utilidad de análisis de rendimiento (dotnet-trace) (documentación del repositorio de GitHub sobre diagnóstico y dotnet)
- Clase LoggingEventSource (Explorador de API de .NET)
- EventLevel
- Origen de referencia de LoggingEventSource (3.0): Para obtener el origen de referencia de otra versión, cambie la rama a
release/{Version}, donde{Version}corresponde a la versión de ASP.NET Core deseada. - Perfview: es útil para ver los seguimientos del origen de eventos.
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 EventLog no 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-aaaammdd.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:
- Información general de Application Insights
- Application Insights para aplicaciones de ASP.NET Core: comience aquí si quiere implementar la variedad completa de telemetría de Application Insights junto con el registro.
- ApplicationInsightsLoggerProvider para los registros de .NET Core ILogger: comience aquí si quiere implementar el proveedor de registro sin el resto de la telemetría de Application Insights.
- Adaptadores de registro de Application Insights
- Instalación, configuración e inicialización del SDK de Application Insights: tutorial interactivo en el sitio de Microsoft Learn.
Proveedores de registro de terceros
Plataformas de registro de terceros que funcionan con ASP.NET Core:
- elmah.io (repositorio de GitHub)
- Gelf (repositorio de GitHub)
- JSNLog (repositorio de GitHub)
- KissLog.net (repositorio de GitHub)
- Log4Net (repositorio de GitHub)
- Loggr (repositorio de GitHub)
- NLog (repositorio de GitHub)
- PLogger (repositorio de GitHub)
- Sentry (repositorio de GitHub)
- Serilog (repositorio de GitHub)
- Stackdriver (repositorio de GitHub)
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:
- Agregue un paquete NuGet al proyecto.
- Llame a un método de extensión
ILoggerFactoryproporcionado 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 los siguientes ejemplos de ASP.NET Core, 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 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:
- Las interfaces están en Microsoft.Extensions.Logging.Abstractions.
- Las implementaciones predeterminadas se encuentran en Microsoft.Extensions.Logging.
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
Informationy superiores. - Todas las categorías que empiezan con
"Microsoft".
Creación de un registrador personalizado
Para agregar un registrador personalizado, agregue ILoggerProvider con ILoggerFactory:
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddProvider(new CustomLoggerProvider(new CustomLoggerConfiguration()));
ILoggerProvider crea una o más instancias de ILogger. El marco de trabajo usa las instancias de ILogger para registrar la información.
Configuración de registrador personalizado de ejemplo
Ejemplo:
- Está diseñado para ser un ejemplo muy básico que establece el color de la consola de registro por el identificador de evento y el nivel de registro. Normalmente, los registradores no cambian por identificador de evento y no son específicos del nivel de registro.
- Crea diferentes entradas de consola de color por nivel de registro e identificador de evento con el siguiente tipo de configuración:
public class ColorConsoleLoggerConfiguration
{
public LogLevel LogLevel { get; set; } = LogLevel.Warning;
public int EventId { get; set; } = 0;
public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
}
El código anterior establece el nivel predeterminado en Warning y el color en Yellow. Si EventId se establece en 0, se registrarán todos los eventos.
Creación del registrador personalizado
El nombre de la categoría de implementación ILogger es normalmente el origen del registro. Por ejemplo, el tipo en el que se crea el registrador:
public class ColorConsoleLogger : ILogger
{
private readonly string _name;
private readonly ColorConsoleLoggerConfiguration _config;
public ColorConsoleLogger(string name, ColorConsoleLoggerConfiguration config)
{
_name = name;
_config = config;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return logLevel == _config.LogLevel;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
if (_config.EventId == 0 || _config.EventId == eventId.Id)
{
var color = Console.ForegroundColor;
Console.ForegroundColor = _config.Color;
Console.WriteLine($"{logLevel} - {eventId.Id} " +
$"- {_name} - {formatter(state, exception)}");
Console.ForegroundColor = color;
}
}
}
El código anterior:
- Crea una instancia del registrador por nombre de categoría.
- Comprueba
logLevel == _config.LogLevelenIsEnabled, por lo que cadalogLeveltiene un registrador único. Por lo general, los registradores también se deben habilitar para todos los niveles de registro superiores:
public bool IsEnabled(LogLevel logLevel)
{
return logLevel >= _config.LogLevel;
}
Creación del proveedor LoggerProvider personalizado
LoggerProvider es la clase que crea las instancias del registrador. Tal vez no sea necesario crear una instancia del registrador por categoría, pero esto tiene sentido para algunos registradores, como NLog o log4net. Al hacerlo, también se podrán elegir diferentes destinos de salida de registro por categoría, en caso necesario:
public class ColorConsoleLoggerProvider : ILoggerProvider
{
private readonly ColorConsoleLoggerConfiguration _config;
private readonly ConcurrentDictionary<string, ColorConsoleLogger> _loggers = new ConcurrentDictionary<string, ColorConsoleLogger>();
public ColorConsoleLoggerProvider(ColorConsoleLoggerConfiguration config)
{
_config = config;
}
public ILogger CreateLogger(string categoryName)
{
return _loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, _config));
}
public void Dispose()
{
_loggers.Clear();
}
}
En el código anterior, CreateLogger crea una única instancia de ColorConsoleLogger por nombre de categoría y la almacena en ConcurrentDictionary<TKey,TValue>.
Uso y registro del registrador personalizado
Registre el registrador en Startup.Configure:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
ILoggerFactory loggerFactory)
{
// Default registration.
loggerFactory.AddProvider(new ColorConsoleLoggerProvider(
new ColorConsoleLoggerConfiguration
{
LogLevel = LogLevel.Error,
Color = ConsoleColor.Red
}));
// Custom registration with default values.
loggerFactory.AddColorConsoleLogger();
// Custom registration with a new configuration instance.
loggerFactory.AddColorConsoleLogger(new ColorConsoleLoggerConfiguration
{
LogLevel = LogLevel.Debug,
Color = ConsoleColor.Gray
});
// Custom registration with a configuration object.
loggerFactory.AddColorConsoleLogger(c =>
{
c.LogLevel = LogLevel.Information;
c.Color = ConsoleColor.Blue;
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Para el código anterior, proporcione al menos un método de extensión para ILoggerFactory:
public static class ColorConsoleLoggerExtensions
{
public static ILoggerFactory AddColorConsoleLogger(
this ILoggerFactory loggerFactory,
ColorConsoleLoggerConfiguration config)
{
loggerFactory.AddProvider(new ColorConsoleLoggerProvider(config));
return loggerFactory;
}
public static ILoggerFactory AddColorConsoleLogger(
this ILoggerFactory loggerFactory)
{
var config = new ColorConsoleLoggerConfiguration();
return loggerFactory.AddColorConsoleLogger(config);
}
public static ILoggerFactory AddColorConsoleLogger(
this ILoggerFactory loggerFactory,
Action<ColorConsoleLoggerConfiguration> configure)
{
var config = new ColorConsoleLoggerConfiguration();
configure(config);
return loggerFactory.AddColorConsoleLogger(config);
}
}
Recursos adicionales
- Registro de alto rendimiento con LoggerMessage en ASP.NET Core
- Los errores de registro deben crearse en el repositorio github.com/dotnet/runtime/.
- Registro de Blazor en ASP.NET Core
Por Tom Dykstra y Steve Smith
.NET Core es compatible con una API de registro que funciona con una gran variedad de proveedores de registro integrados y de terceros. En este artículo se muestra cómo usar las API de registro con proveedores integrados.
Vea o descargue el código de ejemplo (cómo descargarlo)
Incorporación de proveedores
Un proveedor de registro muestra o almacena registros. Por ejemplo, el proveedor de consola muestra los registros en la consola y el proveedor de Azure Application Insights los almacena en Azure Application Insights. Los registros se pueden enviar a varios destinos mediante la incorporación de varios proveedores.
Para usar un proveedor, llame al método de extensión Add{provider name} del proveedor en Program.cs:
public static void Main(string[] args)
{
var webHost = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json",
optional: true, reloadOnChange: true);
config.AddEnvironmentVariables();
})
.ConfigureLogging((hostingContext, logging) =>
{
// Requires `using Microsoft.Extensions.Logging;`
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
})
.UseStartup<Startup>()
.Build();
webHost.Run();
}
El código anterior requiere referencias a Microsoft.Extensions.Logging y Microsoft.Extensions.Configuration.
La plantilla de proyecto predeterminada llama a CreateDefaultBuilder, que agrega los siguientes proveedores de registro:
- Consola
- Depuración
- EventSource (a partir de ASP.NET Core 2.2)
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
Si usa CreateDefaultBuilder, puede reemplazar los proveedores predeterminados por sus propios valores. Llame a ClearProviders y agregue los proveedores que desee.
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
var todoRepository = host.Services.GetRequiredService<ITodoRepository>();
todoRepository.Add(new Core.Model.TodoItem() { Name = "Feed the dog" });
todoRepository.Add(new Core.Model.TodoItem() { Name = "Walk the dog" });
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Seeded the database.");
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
});
Obtenga más información sobre los proveedores de registro integrados y los proveedores de registro de terceros más adelante en el artículo.
Creación de registros
Para crear registros, use un objeto de ILogger<TCategoryName>. En una aplicación web o servicio hospedado, obtenga un elemento ILogger de la inserción de dependencias. En aplicaciones de consola que no sean de host, use LoggerFactory para crear un elemento ILogger.
En el ejemplo siguiente de ASP.NET Core, se crea un registrador con TodoApiSample.Pages.AboutModel como la categoría. La categoría de registro es una cadena que está asociada con cada registro. La instancia de ILogger<T> proporcionada por la inserción de dependencias genera registros que tienen el nombre completo del tipo T como la categoría.
public class AboutModel : PageModel
{
private readonly ILogger _logger;
public AboutModel(ILogger<AboutModel> logger)
{
_logger = logger;
}
En los siguientes ejemplos de aplicación de consola y ASP.NET Core, el registrador se usa para crear registros con Information como el nivel. El nivel de registro indica la gravedad del evento registrado.
public void OnGet()
{
Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
_logger.LogInformation("Message displayed: {Message}", Message);
}
Los niveles y las categorías se explican detalladamente más adelante en este artículo.
Creación de registros durante el inicio
Para escribir registros en la clase Startup, incluya un parámetro ILogger en la signatura de construcción:
public class Startup
{
private readonly ILogger _logger;
public Startup(IConfiguration configuration, ILogger<Startup> logger)
{
Configuration = configuration;
_logger = logger;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// Add our repository type
services.AddSingleton<ITodoRepository, TodoRepository>();
_logger.LogInformation("Added TodoRepository to services");
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
_logger.LogInformation("In Development environment");
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
}
Crear registros en la clase del programa
Para escribir registros la clase Program, obtenga una instancia ILogger de inserción de dependencias:
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
var todoRepository = host.Services.GetRequiredService<ITodoRepository>();
todoRepository.Add(new Core.Model.TodoItem() { Name = "Feed the dog" });
todoRepository.Add(new Core.Model.TodoItem() { Name = "Walk the dog" });
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Seeded the database.");
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
});
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 CreateWebHostBuilder. AddSerilog usa la configuración estática especificada en Log.Logger:
using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(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 WebHost.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddMvc();
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddConfiguration(builtConfig);
})
.ConfigureLogging(logging =>
{
logging.AddSerilog();
})
.UseStartup<Startup>();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host builder error");
throw;
}
finally
{
Log.CloseAndFlush();
}
}
}
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 los mensajes de registro en un almacén rápido inicialmente y luego moverlos a la tienda lenta. Por ejemplo, si inicia sesión en SQL Server, no desea hacerlo 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.
Configuración
Uno o varios proveedores de configuración proporcionan la configuración del proveedor de registro:
- Formatos de archivo (INI, JSON y XML).
- Argumentos de la línea de comandos.
- Variables de entorno.
- Objetos de .NET en memoria.
- El almacenamiento de administrador secreto sin cifrar.
- Un almacén de usuario cifrado, como Azure Key Vault.
- Proveedores personalizados (instalados o creados).
Por ejemplo, la sección Logging de archivos de configuración de aplicación suele proporcionar la configuración de registro. En el ejemplo siguiente se muestra el contenido de un archivo appsettings.Development.json típico:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
},
"Console":
{
"IncludeScopes": true
}
}
}
La propiedad Logging puede tener LogLevel y propiedades del proveedor de registro (se muestra la consola).
La propiedad LogLevel bajo Logging especifica el nivel mínimo que se va a registrar para las categorías seleccionadas. En el ejemplo, las categorías System y Microsoft se registran en el nivel Information y todas las demás se registran en el nivel Debug.
Otras propiedades bajo Logging especifican proveedores de registro. El ejemplo es para el proveedor de consola. Si un proveedor admite ámbitos de registro, IncludeScopes indica si están habilitados. Una propiedad de proveedor (como Console en el ejemplo) también puede especificar una propiedad LogLevel. LogLevel en un proveedor especifica niveles de registro para ese proveedor.
Si los niveles se especifican en Logging.{providername}.LogLevel, invalidan todo lo establecido en Logging.LogLevel. Por ejemplo, tomemos el siguiente código JSON:
{
"Logging": { // Default, all providers.
"LogLevel": {
"Microsoft": "Warning"
},
"Console": { // Console provider.
"LogLevel": {
"Microsoft": "Information"
}
}
}
}
En el JSON anterior, la configuración del proveedor Console invalida el nivel de registro anterior (predeterminado).
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, FileConfigurationProvider —agregado por CreateDefaultBuilder para leer los archivos de configuración— 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.
Para obtener información sobre cómo implementar proveedores de configuración, consulte Configuración en ASP.NET Core.
Salida de registro de ejemplo
Con el código de ejemplo que se muestra en la sección anterior, los registros aparecen en la consola cuando la aplicación se ejecuta desde la línea de comandos. Este es un ejemplo de salida de la consola:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/api/todo/0
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
info: TodoApi.Controllers.TodoController[1002]
Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
GetById(0) NOT FOUND
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 42.9286ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 148.889ms 404
Los registros anteriores se generaron mediante la realización de una solicitud HTTP GET a la aplicación de ejemplo en http://localhost:5000/api/todo/0.
Este es un ejemplo de los mismos registros tal y como aparecen en la ventana de depuración cuando se ejecuta la aplicación de ejemplo en Visual Studio:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:53104/api/todo/0
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
TodoApi.Controllers.TodoController:Information: Getting item 0
TodoApi.Controllers.TodoController:Warning: GetById(0) NOT FOUND
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 404
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 152.5657ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 316.3195ms 404
Los registros creados por las llamadas de ILogger se muestran en la sección anterior, empezando por “TodoApi”. Los registros que comienzan por categorías de "Microsoft" son del 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.
En el resto de este artículo se explican algunos detalles y opciones para el registro.
Paquetes NuGet
Las interfaces ILogger e ILoggerFactory se encuentran en Microsoft.Extensions.Logging.Abstractions, y sus implementaciones predeterminadas en Microsoft.Extensions.Logging.
Categoría de registro
Cuando se crea un objeto ILogger, se ha especificado una categoría para él. Esa categoría se incluye con cada mensaje de registro creado por esa instancia de ILogger. La categoría puede ser cualquier cadena, pero la convención es usar el nombre de clase, como "TodoApi.Controllers.TodoController".
Use ILogger<T> para obtener una instancia ILogger que utiliza el nombre de tipo completo de T como la categoría:
public class TodoController : Controller
{
private readonly ITodoRepository _todoRepository;
private readonly ILogger _logger;
public TodoController(ITodoRepository todoRepository,
ILogger<TodoController> logger)
{
_todoRepository = todoRepository;
_logger = logger;
}
Para especificar explícitamente la categoría, llame a ILoggerFactory.CreateLogger:
public class TodoController : Controller
{
private readonly ITodoRepository _todoRepository;
private readonly ILogger _logger;
public TodoController(ITodoRepository todoRepository,
ILoggerFactory logger)
{
_todoRepository = todoRepository;
_logger = logger.CreateLogger("TodoApiSample.Controllers.TodoController");
}
ILogger<T> es equivale a llamar a CreateLogger con el nombre de tipo completo de T.
Nivel de registro
Cara registro especifica un valor LogLevel. El nivel de registro indica la gravedad o importancia. Por ejemplo, podría escribir un registro Information cuando un método termina con normalidad y un registro Warning cuando un método devuelve un código de estado 404 No encontrado.
El siguiente código crea los registros Information y Warning:
public IActionResult GetById(string id)
{
_logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
var item = _todoRepository.Find(id);
if (item == null)
{
_logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
return NotFound();
}
return new ObjectResult(item);
}
En el código anterior, los parámetros MyLogEvents.GetItem y MyLogEvents.GetItemNotFound son el id. 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 de registro en este artículo.
Los métodos de registro que incluyen el nivel en el nombre del método (por ejemplo LogInformation y LogWarning) son métodos de extensión para ILogger. Estos métodos llaman a un método Log que toma un parámetro LogLevel. Puede llamar directamente al método Log en lugar de a uno de estos métodos de extensión, pero la sintaxis es relativamente complicada. Para más información, vea la ILogger y el código fuente de las extensiones de registrador.
ASP.NET Core define los niveles de registro siguientes, que aquí se ordenan de menor a mayor gravedad.
Seguimiento = 0
Para información que normalmente solo es útil para la depuración. Estos mensajes pueden contener datos confidenciales de la aplicación, por lo que no deben habilitarse en un entorno de producción. Deshabilitado de forma predeterminada.
Depurar = 1
Para información que puede ser útil para el desarrollo y la depuración. Ejemplo:
Entering method Configure with flag set to true.Habilite los registros de nivelDebugen producción cuando esté solucionando un problema, debido al elevado volumen de registros.Información = 2
Para realizar el seguimiento del flujo general de la aplicación. Estos registros suelen tener algún valor a largo plazo. Ejemplo:
Request received for path /api/todoAdvertencia = 3
Para los eventos anómalos o inesperados en el flujo de la aplicación. Estos pueden incluir errores u otras condiciones que no hacen que la aplicación se detenga, pero que puede que sea necesario investigar. Las excepciones controladas son un lugar común para usar el nivel de registro
Warning. Ejemplo:FileNotFoundException for file quotes.txt.Error = 4
Para los errores y excepciones que no se pueden controlar. Estos mensajes indican un error en la actividad u operación actual (por ejemplo, la solicitud HTTP actual), no un error de toda la aplicación. Mensaje de registro de ejemplo:
Cannot insert record due to duplicate key violation.Crítico = 5
Para los errores que requieren atención inmediata. Ejemplos: escenarios de pérdida de datos, espacio en disco insuficiente.
Use el nivel de registro para controlar la cantidad de salida del registro que se escribe en un medio de almacenamiento determinado o ventana de presentación. Por ejemplo:
- En producción:
- El registro en los niveles
TraceaInformationgenera 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 nivelTraceaInformationen un almacén de datos de alto volumen y bajo costo. - El registro en los niveles
WarningaCriticalnormalmente produce menos mensajes de registro y de menor tamaño. Por lo tanto, los costos y los límites de almacenamiento no suelen ser un problema, lo que da lugar a una mayor flexibilidad a la hora de elegir el almacén de datos.
- El registro en los niveles
- Durante el desarrollo:
- Registre los mensajes
WarningaCriticalen la consola. - Agregue los mensajes
TraceaInformational solucionar problemas.
- Registre los mensajes
En la sección Filtrado del registro de este artículo se explica cómo controlar los niveles de registro que controla un proveedor.
ASP.NET Core escribe registros de eventos de marco. En los ejemplos de registro anteriores de este artículo se excluyeron los registros por debajo del nivel Information, por lo que no se crearon los registros de nivel Debug o Trace. Este es un ejemplo de registros de consola generados mediante la ejecución de la aplicación de ejemplo configurada para mostrar registros Debug:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:62555/api/todo/0
dbug: Microsoft.AspNetCore.Routing.Tree.TreeRouter[1]
Request successfully matched the route with name 'GetTodo' and template 'api/Todo/{id}'.
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
Action 'TodoApi.Controllers.TodoController.Update (TodoApi)' with id '089d59b6-92ec-472d-b552-cc613dfd625d' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
Action 'TodoApi.Controllers.TodoController.Delete (TodoApi)' with id 'f3476abe-4bd9-4ad3-9261-3ead09607366' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action TodoApi.Controllers.TodoController.GetById (TodoApi)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
info: TodoApi.Controllers.TodoController[1002]
Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
GetById(0) NOT FOUND
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action method TodoApi.Controllers.TodoController.GetById (TodoApi), returned result Microsoft.AspNetCore.Mvc.NotFoundResult.
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 0.8788ms
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HL6L7NEFF2QD" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 2.7286ms 404
Id. de evento del registro
Cada registro se puede especificar un id. de evento. La aplicación de ejemplo lo hace mediante una clase LoggingEvents definida de forma local:
public IActionResult GetById(string id)
{
_logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
var item = _todoRepository.Find(id);
if (item == null)
{
_logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
return NotFound();
}
return new ObjectResult(item);
}
public class LoggingEvents
{
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 GetItemNotFound = 4000;
public const int UpdateItemNotFound = 4001;
}
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.TodoController[1002]
Getting item invalidid
warn: TodoApi.Controllers.TodoController[4000]
GetById(invalidid) NOT FOUND
Plantilla de mensaje de registro
Cada registro especifica 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.
public IActionResult GetById(string id)
{
_logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
var item = _todoRepository.Find(id);
if (item == null)
{
_logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
return NotFound();
}
return new ObjectResult(item);
}
El orden de los marcadores de posición, no sus nombres, determina qué parámetros se usan para proporcionar sus valores. En el código siguiente, tenga en cuenta que los nombres de parámetro están fuera de la secuencia en la plantilla de mensaje:
string p1 = "parm1";
string p2 = "parm2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);
Este código crea un mensaje de registro con los valores de parámetro en secuencia:
Parameter values: parm1, parm2
La plataforma de registro funciona de esta manera para que los proveedores de registro puedan implementar el registro semántico, también conocido como registro estructurado. Los propios argumentos se pasan al sistema de registro, no solo a la plantilla de mensaje con formato. Esta información permite a los proveedores de registro almacenar los valores de parámetro como campos. Por ejemplo, suponga que las llamadas del método del registrador tiene el aspecto siguiente:
_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);
Si envía los registros a Azure Table Storage, cada entidad de Azure Table puede tener propiedades ID y RequestTime, lo que simplifica las consultas en los datos de registro. Una consulta puede buscar todos los registros dentro de un intervalo RequestTime determinado sin analizar el tiempo de espera del mensaje de texto.
Excepciones de registro
Los métodos de registrador tienen sobrecargas que le permiten pasar una excepción, como en el ejemplo siguiente:
catch (Exception ex)
{
_logger.LogWarning(LoggingEvents.GetItemNotFound, ex, "GetById({Id}) NOT FOUND", id);
return NotFound();
}
return new ObjectResult(item);
Cada proveedor controla la información de la excepción de maneras diferentes. Este es un ejemplo de salida del proveedor de depuración del código mostrado anteriormente.
TodoApiSample.Controllers.TodoController: Warning: GetById(55) NOT FOUND
System.Exception: Item not found exception.
at TodoApiSample.Controllers.TodoController.GetById(String id) in C:\TodoApiSample\Controllers\TodoController.cs:line 226
Filtrado del registro
Puede especificar un nivel de registro mínimo para un proveedor y una categoría específicos, o para todos los proveedores o todas las categorías. Los registros por debajo del nivel mínimo no se pasan a ese proveedor, de modo que no se muestran o almacenan.
Para suprimir todos los registros, especifique LogLevel.None como el nivel de registro mínimo. El valor entero de LogLevel.None es 6, que es superior a LogLevel.Critical (5).
Creación de reglas de filtro en la configuración
El código de la plantilla de proyecto llama a CreateDefaultBuilder para configurar el registro para los proveedores de Console, Debug y EventSource (ASP.NET Core 2.2 o versiones posteriores). El método CreateDefaultBuilder configura el registro para buscar la configuración en una sección de Logging, como se explica anteriormente en este artículo.
Los datos de configuración especifican niveles de registro mínimo por proveedor y categoría, como en el ejemplo siguiente:
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": false,
"LogLevel": {
"Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
"Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
"Microsoft.AspNetCore.Mvc.Razor": "Error",
"Default": "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}
}
Este archivo JSON crea seis reglas de filtro, una para el proveedor de depuración, cuatro para el proveedor de la consola y una para todos los proveedores. Se elige una sola regla para cada proveedor cuando se crea un objeto ILogger.
Reglas de filtro en el código
En el siguiente ejemplo se muestra cómo registrar reglas de filtro en el código:
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
logging.AddFilter("System", LogLevel.Debug)
.AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Trace));
El segundo AddFilter especifica el proveedor de depuración mediante su nombre de tipo. El primer AddFilter se aplica a todos los proveedores, dado que no especifica un tipo de proveedor.
Cómo se aplican las reglas de filtro
Los datos de configuración y el código de AddFilter que se muestran en los ejemplos anteriores crean las reglas que se muestran en la tabla siguiente. Las seis primeras proceden del ejemplo de configuración y las dos últimas del ejemplo de código.
| número | Proveedor | Categorías que comienzan por... | Nivel de registro mínimo |
|---|---|---|---|
| 1 | Depuración | Todas las categorías | Información |
| 2 | Consola | Microsoft.AspNetCore.Mvc.Razor.Internal | Advertencia |
| 3 | Consola | Microsoft.AspNetCore.Mvc.Razor.Razor | Depuración |
| 4 | Consola | Microsoft.AspNetCore.Mvc.Razor | Error |
| 5 | Consola | Todas las categorías | Información |
| 6 | Todos los proveedores | Todas las categorías | Depuración |
| 7 | Todos los proveedores | Sistema | Depuración |
| 8 | Depuración | Microsoft | Seguimiento |
Cuando se crea un objeto ILogger, 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 posible 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.
Con la lista de reglas anterior, supongamos que crea un objeto ILogger para la categoría "Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine":
- Para el proveedor de depuración, se aplican las reglas 1, 6 y 8. La regla 8 es la más específica, por lo que se selecciona.
- Para el proveedor de la consola, se aplican las reglas 3, 4, 5 y 6. La regla 3 es la más específica.
La instancia ILogger resultante envía los registros de nivel Trace y superiores al proveedor de depuración. Los registros de nivel Debug y superiores se envían al proveedor de consola.
Alias de proveedor
Cada proveedor define un alias que se puede utilizar en la configuración en lugar del nombre de tipo completo. Para los proveedores integrados, use los alias siguientes:
- Consola
- Depuración
- EventSource
- EventLog
- TraceSource
- AzureAppServicesFile
- AzureAppServicesBlob
- ApplicationInsights
Nivel mínimo predeterminado
Hay una configuración de nivel mínimo que solo tiene efecto si no se aplica ninguna regla de configuración o código para un proveedor y una categoría determinados. En el ejemplo siguiente se muestra cómo establecer el nivel mínimo:
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning));
Si no establece explícitamente el nivel mínimo, el valor predeterminado es Information, lo que significa que los registros Trace y Debug se omiten.
Funciones de filtro
Se invoca una función de filtro para todos los proveedores y categorías que no tienen reglas asignadas mediante configuración o código. El código de la función tiene acceso al tipo de proveedor, la categoría y el nivel de registro. Por ejemplo:
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logBuilder =>
{
logBuilder.AddFilter((provider, category, logLevel) =>
{
if (provider == "Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider" &&
category == "TodoApiSample.Controllers.TodoController")
{
return false;
}
return true;
});
});
Niveles y categorías del sistema
Estas son algunas categorías que ASP.NET Core y Entity Framework Core usan, con notas sobre lo que los registros de espera de ellas:
| 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. |
Á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 es un tipo IDisposable devuelto por el método BeginScope y se conserva hasta que se elimina. Use un ámbito encapsulando las llamadas de registrador en un bloque using:
public IActionResult GetById(string id)
{
TodoItem item;
using (_logger.BeginScope("Message attached to logs created in the using block"))
{
_logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
item = _todoRepository.Find(id);
if (item == null)
{
_logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
return NotFound();
}
}
return new ObjectResult(item);
}
El código siguiente permite ámbitos para el proveedor de la consola:
Program.cs:
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole(options => options.IncludeScopes = true);
logging.AddDebug();
})
Nota
Es necesario configurar la opción del registrador de consola IncludeScopes para habilitar el registro basado en el ámbito.
Para obtener información sobre la configuración, consulte la sección Configuración.
Cada mensaje de registro incluye la información de ámbito:
info: TodoApiSample.Controllers.TodoController[1002]
=> RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApiSample.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block
Getting item 0
warn: TodoApiSample.Controllers.TodoController[4000]
=> RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApiSample.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block
GetById(0) NOT FOUND
Proveedores de registro integrados
ASP.NET Core incluye los proveedores siguientes:
- Consola
- Depurar
- EventSource
- EventLog
- TraceSource
- AzureAppServicesFile
- AzureAppServicesBlob
- ApplicationInsights
Para obtener información sobre stdout y el registro de depuración 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.
Proveedor de la consola
El paquete de proveedor Microsoft.Extensions.Logging.Console envía la salida del registro a la consola.
logging.AddConsole();
Para ver una salida de registro de la consola, abra un símbolo del sistema en la carpeta del proyecto y ejecute este comando:
dotnet run
Proveedor de depuración
El paquete de proveedor Microsoft.Extensions.Logging.Debug escribe la salida del registro mediante la clase System.Diagnostics.Debug (llamadas a métodos Debug.WriteLine).
En Linux, este proveedor escribe registros en /var/log/message.
logging.AddDebug();
Proveedor de origen del evento
El paquete del proveedor Microsoft.Extensions.Logging.EventSource escribe en una multiplataforma de origen del evento con el nombre Microsoft-Extensions-Logging. En Windows, el proveedor utiliza ETW.
logging.AddEventSourceLogger();
El proveedor de origen del evento se agrega automáticamente cuando se llama a CreateDefaultBuilder para compilar el host.
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 asterisco al principio de la cadena).

Proveedor EventLog de Windows
El paquete de proveedor Microsoft.Extensions.Logging.EventLog envía la salida del registro al Registro de eventos de Windows.
logging.AddEventLog();
Las sobrecargas de AddEventLog permiten 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.
Los eventos se registran para el Nivel de advertencia y superior. En el ejemplo siguiente se establece el nivel de registro predeterminado del Registro de eventos en LogLevel.Information:
"Logging": {
"EventLog": {
"LogLevel": {
"Default": "Information"
}
}
}
Proveedor TraceSource
El paquete de proveedor Microsoft.Extensions.Logging.TraceSource usa las bibliotecas y proveedores de TraceSource.
logging.AddTraceSource(sourceSwitchName);
Las sobrecargas de AddTraceSource permiten pasar un modificador de origen y un agente de escucha de seguimiento.
Para usar este proveedor, una aplicación debe ejecutarse en .NET Framework (en lugar de .NET Core). El proveedor puede enrutar mensajes a una variedad de agentes de escucha, como TextWriterTraceListener que se usa en la aplicación de ejemplo.
Proveedor 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.
logging.AddAzureWebAppDiagnostics();
El paquete de proveedor no está incluido en el metapaquete Microsoft.AspNetCore.App. Si el destino es .NET Framework o hace referencia al metapaquete Microsoft.AspNetCore.App, agregue el paquete del proveedor al proyecto.
Una sobrecarga AddAzureWebAppDiagnostics permite pasar AzureAppServicesDiagnosticsSettings. El objeto de configuración puede invalidar la configuración predeterminada, como la plantilla de salida de registro, el nombre de blob y el límite de tamaño de archivo. (La plantilla salida es una plantilla de mensaje que se aplica a todos los registros además de que se proporciona con una llamada de método ILogger).
Al realizar una implementación en una aplicación de App Service, esta respeta 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-aaaammdd.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 funciona cuando el proyecto se ejecuta en el entorno de Azure. No tiene ningún efecto cuando el proyecto se ejecuta de manera local (no escribe en los archivos locales ni en el almacenamiento de desarrollo local de blobs).
Secuencias de registro de Azure
Las secuencias 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:
- Navegue hasta la página Registros de App Service desde la página de portal de la aplicación.
- Establezca Registro de la aplicación (sistema de archivos) en Activado.
- Elija el Nivel de registro. Este valor solo se aplica a las secuencias de registro de Azure, no a otros proveedores de registro de la aplicación.
Navegue hasta la página Secuencia de registro para consultar los mensajes de la aplicación. La aplicación los registra a través de la interfaz ILogger.
Registro de seguimiento de Azure Application Insights
El proveedor de paquete 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.
No use el paquete Microsoft.ApplicationInsights.Web—que es para ASP.NET 4.x.
Para obtener más información, vea los siguientes recursos:
- Información general de Application Insights
- Application Insights para aplicaciones de ASP.NET Core: comience aquí si quiere implementar la variedad completa de telemetría de Application Insights junto con el registro.
- ApplicationInsightsLoggerProvider para los registros de .NET Core ILogger: comience aquí si quiere implementar el proveedor de registro sin el resto de la telemetría de Application Insights.
- Adaptadores de registro de Application Insights
- Instalación, configuración e inicialización del SDK de Application Insights: tutorial interactivo en el sitio de Microsoft Learn.
Proveedores de registro de terceros
Plataformas de registro de terceros que funcionan con ASP.NET Core:
- elmah.io (repositorio de GitHub)
- Gelf (repositorio de GitHub)
- JSNLog (repositorio de GitHub)
- KissLog.net (repositorio de GitHub)
- Log4Net (repositorio de GitHub)
- Loggr (repositorio de GitHub)
- NLog (repositorio de GitHub)
- Sentry (repositorio de GitHub)
- Serilog (repositorio de GitHub)
- Stackdriver (repositorio de GitHub)
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:
- Agregue un paquete NuGet al proyecto.
- Llame a un método de extensión
ILoggerFactoryproporcionado 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.