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.
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.