Matthew Flynn
Matthew Flynn

Reputation: 3931

Configuring Serilog ASP.Net Core 3.2 with EF Core to log SQL statments

Previously when using the Microsoft.Extensions.Logging I would inject the ILoggerFactory and .UseLoggingFactory() when setting up my DbContext as follows (reduced for brevity);

    private readonly ILoggerFactory LoggerFactory;


    public Startup(... ILoggerFactory loggerFactory)
    {
        LoggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
    }

    public void ConfigureServices(IServiceCollection services)
    {
        var connectionString = Configuration.GetConnectionString($"DbDataContext");

        services.AddDbContext<OakfieldLeasingDataContext>(
            options => options
                .UseSqlServer(
                    connectionString,
                    x => x.UseNetTopologySuite())
                .UseLoggerFactory(LoggerFactory));
     }

I am trying to now swap in Serilog, I have successfully changed my Program.cs as follows;

    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
        .Enrich.FromLogContext()
        .WriteTo.Console(new RenderedCompactJsonFormatter())
        .WriteTo.File(new RenderedCompactJsonFormatter(), "./logs/log.ndjson")
        .CreateLogger();

        try
        {
            Log.Information("Starting up");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Application start-up failed");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
        .UseSerilog() 
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

and can successfully confirm the log is going to the log file. However, with the existing code I get the following error;

System.InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILoggerFactory' while attempting to activate 'Blazor.Server.Startup'.

Can anyone advise how I can inject the Serilog LoggerFactory to EF Core to log the SQL generation please?

Upvotes: 3

Views: 17630

Answers (3)

Ren&#233;
Ren&#233;

Reputation: 3711

With the settings in the Main-Method and the CreateHostBuilder-Method provided by the Original Poster the SerilogLoggerFactory will be available for injection.

You can inject the LoggerFactory in the constructor of your DbContext-Class like this:

public MyDbContext(DbContextOptions<MyDbContext> options, ILoggerFactory loggerFactory)
        : base(options)
    {
       _loggerFactory = loggerFactory;
    }

Then you can set it in the OnConfiguring Method of your DbContext class like this:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("MyConnectionString");
        optionsBuilder.UseLoggerFactory(_loggerFactory);

        optionsBuilder.EnableSensitiveDataLogging(); // optional
        optionsBuilder.EnableDetailedErrors(); // optional
        ... // for other settings see [here][1]
    }

Upvotes: 1

Sk Shahnawaz-ul Haque
Sk Shahnawaz-ul Haque

Reputation: 588

You need to include the DB context in the following way:

services.AddDbContext<OakfieldLeasingDataContext>(
        options => options
            .UseSqlServer(
                connectionString,
                x => x.UseNetTopologySuite())
            .LogTo(Log.Logger.Information, LogLevel.Information, null));

Upvotes: 8

Liam Kernighan
Liam Kernighan

Reputation: 2525

Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseSerilog()
                .MinimumLevel.Override("Microsoft.EntityFrameworkCore", Serilog.Events.LogEventLevel.Information)
                    .WriteTo.Console(restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Verbose))

Upvotes: 7

Related Questions