SeriLog和.NET Core 2.1 HostBuilder配置

Mr.*_*. T 9 c# serilog .net-core-2.1

我正在使用.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我需要调用才能loggingBuilder.AddSerilog()使用在ILogger上面几行中使用DI服务配置注册的单例.

我意识到我可以直接调用BuildLogger()获取ILogger实例并使用DI服务配置注册该实例,但似乎我不应该这样做.我正在寻找的是一种方法,从.ConfigureLogging()方法中访问一个ServiceProvider实例,所以我可以得到注册ILogger可能喜欢

serviceProvider.GetRequiredService<ILogger>();
Run Code Online (Sandbox Code Playgroud)

并将其传递给AddSerilog()电话.有任何想法吗?

mer*_*bla 11

尝试现在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();
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的指点——那个包裹真的是全新的。但我正在寻找一种在“ConfigureServices()”中注册“ILogger”实例的方法,然后在“UseSerilog()”调用中从DI框架访问它。默认行为依赖于静态全局“Log.Logger”实例,这违背了依赖注入的全部目的。 (3认同)

Cor*_*ens 8

我正在寻找的是一种方法,从.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();
}

...//
Run Code Online (Sandbox Code Playgroud)


Thu*_*kwa 6

这是一个示例,展示了如何执行此操作,包括使用 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)