Uso di Microsoft.Extensions.Logging in EF Core
Microsoft.Extensions.Logging è un meccanismo di registrazione estendibile con provider di plug-in per molti sistemi di registrazione di uso comune. Entrambi i plug-in forniti da Microsoft (ad esempio Microsoft.Extensions.Logging.Console) e plug-in di terze parti (ad esempio Serilog.Extensions.Logging) sono disponibili come pacchetti NuGet.
Entity Framework Core (EF Core) si integra completamente con Microsoft.Extensions.Logging
. È tuttavia consigliabile usare la registrazione semplice per un modo più semplice per registrare, in particolare per le applicazioni che non usano l'inserimento delle dipendenze.
applicazioni core ASP.NET
Microsoft.Extensions.Logging
viene usato per impostazione predefinita nelle applicazioni core di ASP.NET. La chiamata AddDbContext o AddDbContextPool rende EF Core usa automaticamente la configurazione della registrazione configurata tramite il normale meccanismo di ASP.NET.
Altri tipi di applicazione
Altri tipi di applicazione possono usare GenericHost per ottenere gli stessi modelli di inserimento delle dipendenze usati in ASP.NET Core. AddDbContext oppure AddDbContextPool può essere usato esattamente come nelle applicazioni ASP.NET Core.
Microsoft.Extensions.Logging
può essere usato anche per le applicazioni che non usano l'inserimento delle dipendenze, anche se la registrazione semplice può essere più semplice da configurare.
Microsoft.Extensions.Logging
richiede la creazione di un oggetto LoggerFactory. Questa factory deve essere archiviata come istanza statica/globale da qualche parte e usata ogni volta che viene creato un Oggetto DbContext. Ad esempio, è comune archiviare la factory del logger come proprietà statica in DbContext.
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder => { builder.AddConsole(); });
Questa istanza singleton/globale deve quindi essere registrata con EF Core in DbContextOptionsBuilder. Ad esempio:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory)
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True;ConnectRetryCount=0");
Recupero di messaggi dettagliati
Suggerimento
OnConfiguring viene comunque chiamato quando si usa AddDbContext o un'istanza DbContextOptions viene passata al costruttore DbContext. Ciò rende la posizione ideale per applicare la configurazione del contesto indipendentemente dalla modalità di costruzione di DbContext.
Dati sensibili
Per impostazione predefinita, EF Core non includerà i valori dei dati nei messaggi di eccezione. Ciò è dovuto al fatto che tali dati possono essere riservati e potrebbero essere rivelati nell'uso in produzione se non viene gestita un'eccezione.
Tuttavia, conoscere i valori dei dati, soprattutto per le chiavi, può essere molto utile durante il debug. Questa opzione può essere abilitata in EF Core chiamando EnableSensitiveDataLogging(). Ad esempio:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.EnableSensitiveDataLogging();
Eccezioni di query dettagliate
Per motivi di prestazioni, EF Core non esegue il wrapping di ogni chiamata per leggere un valore dal provider di database in un blocco try-catch. Tuttavia, ciò comporta talvolta eccezioni difficili da diagnosticare, soprattutto quando il database restituisce un valore NULL quando non è consentito dal modello.
L'attivazione EnableDetailedErrors causerà l'introduzione di questi blocchi try-catch da parte di Entity Framework e in tal modo fornirà errori più dettagliati. Ad esempio:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.EnableDetailedErrors();
Configurazione per messaggi specifici
L'API EF Core ConfigureWarnings consente alle applicazioni di modificare ciò che accade quando viene rilevato un evento specifico. Questo può essere usato per:
- Modificare il livello di log a cui viene registrato l'evento
- Ignorare completamente la registrazione dell'evento
- Generare un'eccezione quando si verifica l'evento
Modifica del livello di log per un evento
A volte può essere utile modificare il livello di log predefinito per un evento. Ad esempio, questo può essere usato per alzare di livello due eventi aggiuntivi da LogLevel.Debug
a LogLevel.Information
:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(
b => b.Log(
(RelationalEventId.ConnectionOpened, LogLevel.Information),
(RelationalEventId.ConnectionClosed, LogLevel.Information)));
Eliminare la registrazione di un evento
In modo analogo, un singolo evento può essere eliminato dalla registrazione. Ciò è particolarmente utile per ignorare un avviso che è stato esaminato e compreso. Ad esempio:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Ignore(CoreEventId.DetachedLazyLoadingWarning));
Generare un evento
Infine, EF Core può essere configurato per generare un determinato evento. Ciò è particolarmente utile per modificare un avviso in un errore. (Infatti, questo era lo scopo originale del ConfigureWarnings
metodo, quindi il nome. Per esempio:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Throw(RelationalEventId.QueryPossibleUnintendedUseOfEqualsWarning));
Filtro e altre configurazioni
Per indicazioni sul filtro dei log e su altre configurazioni, vedere Registrazione in .NET .
Gli eventi di registrazione di EF Core sono definiti in uno dei seguenti:
- CoreEventId per gli eventi comuni a tutti i provider di database EF Core
- RelationalEventId per gli eventi comuni a tutti i provider di database relazionali
- Classe simile per gli eventi specifici del provider di database corrente. Ad esempio, SqlServerEventId per il provider SQL Server.
Queste definizioni contengono gli ID evento, il livello di log e la categoria per ogni evento, come usato da Microsoft.Extensions.Logging
.