Logging in EF Core

In this article let us find out how Logging in EF Core works. We use logging to Log SQL queries. Find out more about errors. Improve Performance of the SQL Queries etc. In the article, we will create an example application and show you how to log queries to console and also to the windows event log. We also show you how to filter the logs using the log levels & DbLogger Category.

Why Logging

There are a lot of scenarios, where you would see the queries the EF Core generates. For Example, the Query may fail to bring the desired result or when the query itself is slow. Looking and analyzing the query that is sent to the back end server help us to write better queries and fine-tune performance bottlenecks.

EF Core has come with a lot of logging capabilities out of the box. All we need to capture it and direct it to a text file or console or another database.

Logging in .NET Core

.NET Core apps have built-in mechanisms for creating & managing various loggers. At the heart of the Logging API is three players LoggerProvider, Logger & LoggerFactory.

Logger is what writes the log entities to output. The output can be a console, database a text file etc. It must implement the interface ILogger

The LoggerProvider must implement the interface ILoggerProvider. The responsibility of the LoggerProvider to create the Logger. The re are many built-in LoggerProviders available for us to use. The following is the list of some of them.

Logger ProvidersDescription
Microsoft.Extensions.Logging.ConsoleA simple console logger
Microsoft.Extensions.Logging.AzureAppServicesSupports Azure App Services 'Diagnostics logs' and 'Log stream' features.
Microsoft.Extensions.Logging.DebugLogs to a debugger monitor using System.Diagnostics.Debug.WriteLine()
Microsoft.Extensions.Logging.EventLogLogs to Windows Event Log
Microsoft.Extensions.Logging.EventSourceupports EventSource/EventListener
Microsoft.Extensions.Logging.TraceSourceLogs to a trace listener using System.Diagnostics.TraceSource.TraceEvent()

The LoggerFactory contains the collection of LoggerProvider. We add the LoggerProvider to the LoggerFactory. Since it is a collection, it gives us the ability to log to multiple locations using different providers. It is the responsibility of the LoggerFactory to create the instance of the ILoggerProvider. The LoggerProvider then creates the instance of the Logger.

Logging To Console

The DBContext generates a lot of log information. All we need to do is tie up the LoggerProvider to it.

The way it is done in a console application is a little different from an ASP.NET Core application. In ASP.NET Core apps the LoggerFactory is already set up by the framework. It is also automatically tied up to the DBContext class.

EF Core Console App

First, create an EF Core Console Application as shown in the tutorial. The tutorial uses Visual Studio 2017. But you can also use the Visual Studio 2019 and Dot net core 3.x.

Console Logger Provider

The next step is to install the Logger Provider. The list above contains some of the built in loggers. Let us use the Console Logger Provider. Install it using the following command.

Logger Factory & Logger Provider

First, we need to create the Logger Factory

Open the EFContext class and add the following at top

We LoggerFactory.Create is a static method, which creates the LoggerFactory. It gets the builder as its argument. The purpose of it is to configure the LoggerProvider.

We declare the MyLoggerFactory as static. Because the Context must use the same instance of the LoggerFactory for the entire duration of the application lifetime. Otherwise, it will have performance side effects

The AddConsole is an extension method from the Microsoft.Extensions.Logging.Console package. It configures the LoggerProvider and adds it the LoggerFactory.

With this our LoggerFactory is ready. Now time to hook it up to the DBContext. We do it while Configuring the DBContext using the OnConfiguring Method. Pass our LoggerFactory using the UseLoggerFactory method.

Now, run the app and you will see the select query in your console screen.

Configure Logger

The above code logs everything, which is going to fill up the console. The logger provides a lot of filters to keep the log entries to minimum

EnableDetailedErrors

This EnableDetailedErrors option provides additional error details about the errors. Such errors most often about the misconfigured entity properties like int in place of string etc. This option is set to false by default. But when set to true it will include details of the specific entity property that generated the error. Enabling this option will incur a small performance hit.

EnableSensitiveDataLogging

The EnableSensitiveDataLogging enables application data to include sensitive information in the logs. The sensitive information include the values assigned to properties of your entity instances, parameter values for commands being sent to the database, etc

Log Levels

The Logs are classified according to severity levels. The following table shows

NameValueDescription
Trace0Logs that contain the most detailed messages. These messages may contain sensitive application data. These messages are disabled by default and should never be enabled in a production environment.
Debug1Logs that are used for interactive investigation during development. These logs should primarily contain information useful for debugging and have no long-term value.
Information2Logs that track the general flow of the application. These logs should have long-term value.
Warning3Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the application execution to stop.
Error4Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a failure in the current activity, not an application-wide failure.
Critical5Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention.
None6Not used for writing log messages. Specifies that a logging category should not write any messages

LogLevel Enum

Use the AddFilter method to filter our the desired log level.

DBLogger Category

Apart from the Log Levels, the logger API defines several DBLogger categories. We can use them to filter out the log.

DBLogger CategoryDescription
DbLoggerCategory.ChangeTracking.NameLogger category for messages from change detection and tracking.
DbLoggerCategory.Database.NameLogger categories for messages related to database interactions.
DbLoggerCategory.Database.Connection.NameLogger category for messages related to connection operations.
DbLoggerCategory.Database.Transaction.NameLogger category for messages related to transaction operations.
DbLoggerCategory.Database.Command.NameLogger category for command execution, including SQL sent to the database.
DbLoggerCategory.Infrastructure.NameLogger category for miscellaneous messages from the Entity Framework infrastructure.
DbLoggerCategory.Migrations.NameLogger category messages from Migrations.
DbLoggerCategory.Query.NameLogger category for messages related to queries, excluding the generated SQL, which is in the DbLoggerCategory.Database.Command category.
DbLoggerCategory.Scaffolding.NameLogger category for messages from scaffolding/reverse engineering.
DbLoggerCategory.Update.NameLogger category for messages related to SaveChanges(), excluding messages specifically relating to database interactions which are covered by the DbLoggerCategory.Database categories.
DbLoggerCategory.Model.NameLogger categories for messages related to model building and metadata.
DbLoggerCategory.Model.Validation.NameLogger category for messages from model validation.

Logging To EventLog

Now, you have understood how to implement the logging in EF Core Console Application, we can easily use any other provider. For Example install the following package, which is a LoggerProvider to EventLog

Now, use the AddEventLog extension method to send the logs to the windows event log along with the console. You can also use the addfilter method to filter out the logs.

Summary

Logging in EF core helps us find out more information about the errors. It helps to fine tune our queries, thus helping us in improving the performance.

2 thoughts on “Logging in EF Core”

    1. The above code is limited to capturing the logs from the EF Core (i.e DBContext only).

      If you want to use the log other info then


      public class MyLog
      {
      public static ILoggerFactory factory = LoggerFactory.Create(
      builder =>
      {
      builder.AddConsole();
      builder.AddEventLog();
      }
      );

      public static ILogger logger = factory.CreateLogger("EF");
      }

      And then can use it as MyLog.logger.LogInformation("Log Whatever you want");

      If you want to implement Logging in Console Apps, then it is better to use the DI to inject into the factory and use it.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top