Usar Microsoft.Extensions.Logging en EF Core
Microsoft.Extensions.Logging es un mecanismo de registro extensible con proveedores de complementos para muchos sistemas de registro comunes. Tanto los complementos proporcionados por Microsoft (por ejemplo, Microsoft.Extensions.Logging.Console) como los complementos de terceros (por ejemplo, Serilog.Extensions.Logging) están disponibles como paquetes NuGet.
Entity Framework Core (EF Core) se integra completamente con Microsoft.Extensions.Logging
. Sin embargo, considere la posibilidad de usar el registro sencillo para obtener registros de forma más sencilla, especialmente para las aplicaciones que no usan la inserción de dependencias.
Aplicaciones de ASP.NET Core
Microsoft.Extensions.Logging
se usa de forma predeterminada en aplicaciones ASP.NET Core. Llamar a AddDbContext o AddDbContextPool hace que EF Core use automáticamente la configuración de registro configurada mediante el mecanismo normal de ASP.NET.
Otros tipos de aplicación
Otros tipos de aplicación pueden usar GenericHost para obtener los mismos patrones de inserción de dependencias que se usan en ASP.NET Core. AddDbContext o AddDbContextPool se pueden usar al igual que en aplicaciones ASP.NET Core.
Microsoft.Extensions.Logging
también se puede usar para las aplicaciones que no usan la inserción de dependencias, aunque el registro simple puede ser más fácil de configurar.
Microsoft.Extensions.Logging
requiere la creación de un LoggerFactory. Esta fábrica debe almacenarse como una instancia estática o global en algún lugar y usarse cada vez que se cree dbContext. Por ejemplo, es habitual almacenar el generador de registradores como una propiedad estática en DbContext.
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder => { builder.AddConsole(); });
Esta instancia singleton/global debe registrarse en EF Core en el DbContextOptionsBuilder. Por ejemplo:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory)
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True;ConnectRetryCount=0");
Obtener mensajes detallados
Sugerencia
Se sigue llamando a OnConfiguring cuando se usa AddDbContext o se pasa una instancia DbContextOptions al constructor DbContext. Esto hace que sea el lugar ideal para aplicar la configuración de contexto independientemente de cómo se construya DbContext.
Información confidencial
De forma predeterminada, EF Core no incluirá los valores de ningún dato en los mensajes de excepción. Esto se debe a que estos datos pueden ser confidenciales y podrían revelarse en el uso de producción si una excepción no está controlada.
Sin embargo, conocer los valores de datos, especialmente en las claves, puede ser muy útil al depurar. Esto se puede habilitar en EF Core llamando a EnableSensitiveDataLogging(). Por ejemplo:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.EnableSensitiveDataLogging();
Excepciones de consulta detalladas
Por motivos de rendimiento, EF Core no encapsula cada llamada para leer un valor del proveedor de base de datos en un bloque try-catch. Sin embargo, esto a veces resulta en excepciones difíciles de diagnosticar, especialmente cuando la base de datos devuelve un valor NULL cuando el modelo no lo permite.
Al activar EnableDetailedErrors, EF introducirá estos bloques try-catch y, por tanto, proporcionará errores más detallados. Por ejemplo:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.EnableDetailedErrors();
Configuración de mensajes específicos
La API ConfigureWarnings de EF Core permite a las aplicaciones cambiar lo que sucede cuando se encuentra un evento específico. Esto se puede usar para:
- Cambiar el nivel en el que se registra el evento
- Omitir completamente el registro del evento
- Iniciar una excepción cuando ocurra el evento
Cambiar el nivel de registro de un evento
A veces puede ser útil cambiar el nivel de registro predefinido de un evento. Por ejemplo, esto se puede usar para promover dos eventos adicionales de LogLevel.Debug
a LogLevel.Information
:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(
b => b.Log(
(RelationalEventId.ConnectionOpened, LogLevel.Information),
(RelationalEventId.ConnectionClosed, LogLevel.Information)));
Suprimir el registro de un evento
De forma similar, se puede suprimir un evento individual del registro. Esto es especialmente útil para ignorar una advertencia que se ha revisado y comprendido. Por ejemplo:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Ignore(CoreEventId.DetachedLazyLoadingWarning));
Hacer throw a un evento
Por último, EF Core puede configurarse para hacer throw a un evento determinado. Esto resulta especialmente útil para cambiar que una advertencia pase a ser un error. (De hecho, este era el propósito original del método ConfigureWarnings
, de ahí el nombre). Por ejemplo:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Throw(RelationalEventId.QueryPossibleUnintendedUseOfEqualsWarning));
Filtrado y otra configuración
Consulte Registro en .NET para ver instrucciones sobre el filtrado de registros y otras configuraciones.
Los eventos de registro de EF Core se definen en uno de los siguientes elementos:
- CoreEventId para eventos comunes a todos los proveedores de bases de datos de EF Core
- RelationalEventId para eventos comunes a todos los proveedores de bases de datos relacionales
- Clase similar para eventos específicos del proveedor de base de datos actual. Por ejemplo, SqlServerEventId para el proveedor de SQL Server.
Estas definiciones contienen los identificadores de evento, el nivel de registro y la categoría de cada evento, como lo usa Microsoft.Extensions.Logging
.