10

I'm trying to use Serilog in a .Net Core project. I have 2 services, the 1st one was upgraded from .Net Core 2.2 and in Program.cs it uses IWebHostBuilder to start the application. Here I created my logger and passed it as a parameter to UseSerilog() and everything works as expected.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
      WebHost.CreateDefaultBuilder(args)
        .ConfigureServices(services => services.AddAutofac())
        .UseStartup<Startup>()
        .UseSerilog(_logger);

My 2nd Service was created using the .Net Core 3 templates and it uses IHostBuilder. When I try and use Serilog in either of the following ways I get the same error.

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

or

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

Gives me this error

System.InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger`1[MyService.Startup]' while attempting to activate 'MyService.Startup'.

I have found blog posts that support either apporach but it is the 2nd one that I feel is more correct but neither work. Here is a link to it. The other blog is here.

Jeff Finn
  • 1,975
  • 6
  • 23
  • 52

1 Answers1

16

You do not have to instantiate an instance of a Logger in that way. Instead you can use LoggerConfiguration and its builder methods to create a logger. You can then initialize the static logger on Log.Logger. Calling UseSerilog without any argument should be enough.

public class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .CreateLogger();

        try
        {
            Log.Information("app starting");
            CreateHostBuilder(args).Build().Run();
            Log.Information("app terminated");
        }
        catch (Exception e)
        {
            Log.Fatal("app crashed", e);
        }
        
    }

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

Configuration Basics: https://github.com/serilog/serilog/wiki/Configuration-Basics

Setting up a new Console app: https://github.com/serilog/serilog/wiki/Getting-Started#example-application

You need to take on a dependency on Serilog.Extensions.Hosting to be able to call UseSerilog on the Host builder.

sarvasana
  • 642
  • 4
  • 13
  • 1
    How would you access `builder.Configuration` for `LoggerConfiguration( ) .ReadFrom.Configuration(builder.Configuration)`? – Donkoid Jan 17 '23 at 20:50