Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serilog and .NET Core 2.1 HostBuilder Configuration

I'm using the .NET Core 2.1 HostBuilder class to set up and run a GRPC server and am having trouble getting SeriLog properly configured so that it is used by the .NET Core logging pipeline as well as available (via dependency injection) elsewhere in my app.

class Program
{
    private static async Task Main(string[] args)
    {
        var hostBuilder = new HostBuilder()
            .ConfigureServices((hostContext, services) =>
            {
                services.AddSingleton<ILogger>(BuildLogger);

                // other services here 
            })
            .ConfigureLogging((hostContext, loggingBuilder) =>
                loggingBuilder.AddSerilog(dispose: true));

        await hostBuilder.RunConsoleAsync();
    }

    private static ILogger BuildLogger(IServiceProvider provider)
    {

        // create a (global) logger
        Log.Logger = new LoggerConfiguration() 
            ...
            .CreateLogger();

        return Log.Logger;
    }
}

The problem is that I need the call to loggingBuilder.AddSerilog() to use the singleton ILogger that was registered with the DI services configuration a few lines above.

I realize I could directly call BuildLogger() to get the ILogger instance and register that instance with the DI service configuration, but it seems like I shouldn't have to. What I'm looking for is a way, from within the .ConfigureLogging() method to access a ServiceProvider instance so I can get the registered ILogger maybe like

serviceProvider.GetRequiredService<ILogger>();

and pass that to the AddSerilog() call. Any ideas?

like image 760
Mr. T Avatar asked Jun 06 '18 20:06

Mr. T


People also ask

Does Serilog support .NET Core?

Serilog is a third-party, open-source library that integrates nicely with ASP.NET Core and allows developers to easily log-structured event data to the console, to files, and various kinds of log targets.

What is Serilog in .NET Core?

Serilog is a . NET library that provides diagnostic logging to files, the console, and almost everywhere you would like. Serilog can be used in classic . NET Framework applications and for applications running on the latest and greatest .


2 Answers

Try the new package now available in Serilog - https://github.com/serilog/serilog-extensions-hosting.

  public static IHost BuildHost(string[] args) =>
    new HostBuilder()
        .ConfigureServices(services => services.AddSingleton<IHostedService, PrintTimeService>())
        .UseSerilog() // <- Add this line
        .Build();
like image 196
merbla Avatar answered Sep 17 '22 12:09

merbla


Here is a sample that shows how to do this including using appsettings.json for configuring serilog and how to get the logging using ILogger without having to manually inject it as the marked answer shows and how you can also you IOptions:

    public class Settings
{
    public string Sample { get; set; }
}

public class Service : IHostedService
{
    private readonly ILogger<Service> _logger;
    private Settings _settings;
    public Service(ILogger<Service> logger,
        Settings settings)
    {
        _logger = logger;
        _settings = settings;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

class Program
{
    static async Task Main(string[] args)
    {
        var host = new HostBuilder()
                   .ConfigureHostConfiguration(builder =>
                   {
                       builder.AddJsonFile("hostsettings.json", optional: true);
                   })
                   .ConfigureAppConfiguration((hostContext, builder) =>
                   {
                       builder.AddJsonFile("appsettings.json");
                       builder.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true);
                   })
                   .ConfigureLogging((hostContext, builder) =>
                   {
                       Log.Logger = new LoggerConfiguration()
                                    .ReadFrom.Configuration(hostContext.Configuration).CreateLogger();
                       builder.AddConfiguration(hostContext.Configuration.GetSection("Logging"));
                       builder.AddSerilog(dispose: true);
                   })
                   .ConfigureServices((hostContext, services) =>
                   {
                       var settings = hostContext.Configuration.GetSection("Configuration").Get<Settings>();
                       services.AddSingleton(settings);

                       services.AddHostedService<Service>();
                       services.AddLogging();
                       services.AddOptions();
                   })
                   .Build();

        using (host)
        {
            await host.StartAsync();
            await host.WaitForShutdownAsync();
        }
    }
}
like image 41
Thulani Chivandikwa Avatar answered Sep 18 '22 12:09

Thulani Chivandikwa