public static readonly LoggerFactory MyLoggerFactory
= new LoggerFactory(new[] { new ConsoleLoggerProvider((_, __) => true, true) });
Warning
In EF Core 2.1, It is very important that applications do not create a new LoggerFactory instance for each DbContext instance. Doing so will result in a memory leak and poor performance. This has been fixed in EF Core 3.0 and above.
This singleton/global instance should then be registered with EF Core on the DbContextOptionsBuilder. For example:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory)
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True");
Getting detailed messages
OnConfiguring is still called when AddDbContext is used or a DbContextOptions instance is passed to the DbContext constructor. This makes it the ideal place to apply context configuration regardless of how the DbContext is constructed.
Sensitive data
By default, EF Core will not include the values of any data in exception messages. This is because such data may be confidential, and could be revealed in production use if an exception is not handled.
However, knowing data values, especially for keys, can be very helpful when debugging. This can be enabled in EF Core by calling EnableSensitiveDataLogging(). For example:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.EnableSensitiveDataLogging();
Detailed query exceptions
For performance reasons, EF Core does not wrap each call to read a value from the database provider in a try-catch block. However, this sometimes results in exceptions that are hard to diagnose, especially when the database returns a NULL when not allowed by the model.
Turning on EnableDetailedErrors will cause EF to introduce these try-catch blocks and thereby provide more detailed errors. For example:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.EnableDetailedErrors();
Configuration for specific messages
The EF Core ConfigureWarnings API allows applications to change what happens when a specific event is encountered. This can be used to:
Change the log level at which the event is logged
Skip logging the event altogether
Throw an exception when the event occurs
Changing the log level for an event
Sometimes it can be useful to change the pre-defined log level for an event. For example, this can be used to promote two additional events from LogLevel.Debug
to LogLevel.Information
:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(
b => b.Log(
(RelationalEventId.ConnectionOpened, LogLevel.Information),
(RelationalEventId.ConnectionClosed, LogLevel.Information)));
Suppress logging an event
In a similar way, an individual event can be suppressed from logging. This is particularly useful for ignoring a warning that has been reviewed and understood. For example:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Ignore(CoreEventId.DetachedLazyLoadingWarning));
Throw for an event
Finally, EF Core can be configured to throw for a given event. This is particularly useful for changing a warning into an error. (Indeed, this was the original purpose of ConfigureWarnings
method, hence the name.) For example:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Throw(RelationalEventId.QueryPossibleUnintendedUseOfEqualsWarning));
Filtering and other configuration
See Logging in .NET for guidance on log filtering and other configuration.
EF Core logging events are defined in one of:
CoreEventId for events common to all EF Core database providers
RelationalEventId for events common to all relational database providers
A similar class for events specific to the current database provider. For example, SqlServerEventId for the SQL Server provider.
These definitions contain the event IDs, log level, and category for each event, as used by Microsoft.Extensions.Logging
.