Настройка SeriLog и .NET Core 2.1 HostBuilder - PullRequest
0 голосов
/ 06 июня 2018

Я использую класс .NET Core 2.1 HostBuilder для настройки и запуска сервера GRPC, и у меня возникают проблемы с правильной настройкой SeriLog, чтобы он использовался конвейером ведения журнала .NET Core, а также был доступен (посредством внедрения зависимостей).) в другом месте в моем приложении.

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;
    }
}

Проблема в том, что мне нужен вызов loggingBuilder.AddSerilog() для использования синглтона ILogger, который был зарегистрирован в конфигурации служб DI несколькими строками выше.

Я понимаю, что мог бы напрямую позвонить BuildLogger(), чтобы получить экземпляр ILogger и зарегистрировать этот экземпляр в конфигурации службы DI, но, похоже, мне это не нужно.Я ищу способ доступа к экземпляру ServiceProvider из метода .ConfigureLogging(), чтобы я мог получить зарегистрированный ILogger, например,

serviceProvider.GetRequiredService<ILogger>();

и передать его AddSerilog() звонок.Есть идеи?

Ответы [ 4 ]

0 голосов
/ 02 мая 2019

Вот пример, который показывает, как это сделать, включая использование appsettings.json для настройки serilog и как получить запись в журнал с помощью ILogger без необходимости вручную вводить его, как показывает отмеченный ответ, и как вы также можете использовать 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();
        }
    }
}
0 голосов
/ 07 июня 2018

Попробуйте новый пакет, теперь доступный в 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();
0 голосов
/ 24 июня 2018

То, что я ищу, это способ, из метода .ConfigureLogging () получить доступ к экземпляру ServiceProvider, чтобы я мог получить зарегистрированный ILogger

Вы можете получить доступ к ServiceProvider из метода ConfigureLogging() через ILoggingBuilder.Services.BuildServiceProvider().Вот так:

//...

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(
                loggingBuilder
                    .Services.BuildServiceProvider().GetRequiredService<ILogger>(),
                dispose: true));

    await hostBuilder.RunConsoleAsync();
}

...//
0 голосов
/ 06 июня 2018

В соответствии с документацией по репозиторию для .NET Core 2.0+, позвоните AddSerilog() по предоставленному loggingBuilder и убедитесь, что сначала настроили Serilog:

//...

private static async Task Main(string[] args) {

    Log.Logger = new LoggerConfiguration()
        //...
        .CreateLogger();

    var hostBuilder = new HostBuilder()
        .ConfigureServices((hostContext, services) => {        
            services.AddLogging(loggingBuilder =>
                loggingBuilder.AddSerilog(dispose: true));

            // other services here 
        });

    await hostBuilder.RunConsoleAsync();
}

//...
...