Microsoft.Extensions.Logging is an extensible logging mechanism with plug-in providers for many common logging systems. Both Microsoft-supplied plug-ins (e.g Microsoft.Extensions.Logging.Console) and third-party plug-ins (e.g. Serilog.Extensions.Logging) are available as NuGet packages.
Entity Framework Core (EF Core) fully integrates with Microsoft.Extensions.Logging
. However, consider using simple logging for a simpler way to log, especially for applications that don't use dependency injection.
Microsoft.Extensions.Logging
is used by default in ASP.NET Core applications. Calling AddDbContext or AddDbContextPool makes EF Core automatically use the logging setup configured via the regular ASP.NET mechanism.
Other application types can use the GenericHost to get the same dependency injection patterns as are used in ASP.NET Core. AddDbContext or AddDbContextPool can then be used just like in ASP.NET Core applications.
Microsoft.Extensions.Logging
can also be used for applications that don't use dependency injection, although simple logging can be easier to set up.
Microsoft.Extensions.Logging
requires creation of a LoggerFactory. This factory should be stored as a static/global instance somewhere and used each time a DbContext is created. For example, it is common to store the logger factory as a static property on the DbContext.
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder => { builder.AddConsole(); });
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;ConnectRetryCount=0");
Getting detailed messages
Tip
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 dataBy 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:
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:
These definitions contain the event IDs, log level, and category for each event, as used by Microsoft.Extensions.Logging
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4