我正在使用.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()
来使用在DI服务配置中注册的单例ILogger
几行。
我意识到我可以直接调用BuildLogger()
来获取ILogger
实例并使用DI服务配置注册该实例,但似乎我不应该这样做。我正在寻找一种方法,从.ConfigureLogging()
方法中访问ServiceProvider
实例,这样我就可以获得注册的ILogger
serviceProvider.GetRequiredService<ILogger>();
并将其传递给AddSerilog()
来电。有什么想法吗?
答案 0 :(得分:9)
尝试使用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();
答案 1 :(得分: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();
}
...//
答案 2 :(得分:3)
根据有关.NET Core 2.0+的repo的文档,请在提供的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();
}
//...
答案 3 :(得分:-1)
这里是一个示例,显示了如何执行此操作,包括使用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();
}
}
}