Search code examples
c#entity-framework-coreserilog

EF Core: Can't see any query logs?


I'm trying to see what EF is executing... it worked fine on a new project but I can't seem to get serilog to print it? I am setting the override like so;

var host = Host.CreateDefaultBuilder()
    .ConfigureServices((context, collection) => ServerServiceCollection.AddServices(collection, context.Configuration))
    .UseSerilog((hostContext, _, logger) => 
        logger.ReadFrom.Configuration(hostContext.Configuration)
        .MinimumLevel.Override("Microsoft", LogEventLevel.Verbose))
    .Build();

Solution

  • In your MyCustomDbContext.

    INJECT the following via a constructor:

    Microsoft.Extensions.Logging.ILoggerFactory
    

    (this is so you code to an interface, not a concrete, Serilog is a concrete)

    Then you use the ILoggerFactory that you injected.. to wire up the "as a target for the sql statements that are generated".. as seen below:

    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    
    
    public class MyCustomDbContext : DbContext
    {
        public const string ErrorMessageILoggerFactoryWrapperIsNull = "ILoggerFactory is null";
    
        private readonly Microsoft.Extensions.Logging.ILoggerFactory loggerFactory;
    
        public MyCustomDbContext(
            ILoggerFactoryWrapper loggerFactory,
            DbContextOptions<MyCustomDbContext> options)
            : base(options)
        {
            this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(
                ErrorMessageILoggerFactoryWrapperIsNull,
                (Exception)null);
    
            /* note, the base-class checks for null for the DbContextOptions-"options" */
    
        }
    
    
            // your "DbSet's" HERE, now shown.
    
    
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
    
            // null is possible if you are using an IDesignTimeDbContextFactory
            // below, you should also consider the use of IHostEnvironment values .. to avoid putting sql-statements in production.  see : https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.hostenvironmentenvextensions.isdevelopment?view=dotnet-plat-ext-8.0
    
    
    
            if (null != this.loggerFactory)
            {
                //// NOT SHOWN :::  Probably should not log sql statements in production, so use hostEnvironment "flags" to only do it when a developer is involved.
                ///but below..is the primary "magic" to get Sql statements to show up.
                optionsBuilder.UseLoggerFactory(this.loggerFactory);
                
                // other non-related options shown above
                //optionsBuilder.EnableSensitiveDataLogging();
                //optionsBuilder.EnableDetailedErrors();
            }
        }
    

    Of course.. after you know (via this answser) .. the magic method names.. it is easy to internet-search and find articles like this:

    https://www.infoworld.com/article/3679528/how-to-work-with-logging-in-entity-framework-core-7.html

    And .. at microsoft.

    https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/extensions-logging?tabs=v3#other-application-types

    IMHO, don't fall for the lure of "easy". (in the microsoft article). take a few minutes and wire up your "real" ILoggerFactory / ILogger.

    write to the "console"... is short sighted.