I follow this article. Developing a sink
But I need to injection IHttpClientFactory.
public class MySink : ILogEventSink
{
//...
public MySink(IFormatProvider formatProvider, IHttpClientFactory httpClientFactory)
{
//...
}
}
public static class MySinkExtensions
{
public static LoggerConfiguration MySink(
this LoggerSinkConfiguration loggerConfiguration,
IHttpClientFactory httpClientFactory,
IFormatProvider formatProvider = null,
LogEventLevel restrictedToMinimumLevel = LogEventLevel.Verbose)
{
return loggerConfiguration.Sink(new MySink(formatProvider, httpClientFactory), restrictedToMinimumLevel);
}
}
Program Main:
class Program
{
static async Task Main(string[] args)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddHttpClient();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.WriteTo.MySink(null) //<--How to get IHttpClientFactory?
.CreateLogger();
services.AddLogging(configure => configure.ClearProviders().AddSerilog(logger));
var serviceProvider = services.BuildServiceProvider();
}
}
appsettings:
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "MyTestProject" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Debug"
}
},
{
"Name": "MySink",
"Args": {
"restrictedToMinimumLevel": "Warning"
}
}
]
}
Can I use the Args to injection IHttpClientFactory?
Or handle this in Main method?
Note: I am using net core console application.
Update: According to the asnwer
Now, the Program Main is:
class Program
{
static async Task Main(string[] args)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddHttpClient();
serviceCollection.AddSingleton<Serilog.ILogger>(sp =>
{
var httpClientFactory = sp.GetRequiredService<IHttpClientFactory>();
return new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.MySink(httpClientFactory)
.CreateLogger();
});
serviceCollection.AddLogging(configure => configure.ClearProviders().AddSerilog());
var serviceProvider = serviceCollection.BuildServiceProvider();
Log.Logger = serviceProvider.GetRequiredService<Serilog.ILogger>();
}
}
And I can injection ILogger in other class
class Test
{
private readonly ILogger<Test> _logger;
Test(ILogger<Test> logger)
{
_logger = logger;
}
}
Update: (2020-07-01)
Now, in asp net core, this package supply dependency injection.
.UseSerilog((hostingContext, services, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.SomeSink(services.GetRequiredService<ISomeDependency>()));
IHttpClientFactory? For a sink you would just pass in configuration options e.g. a URL etc. as the sink would know what it needs to create i.e. an HttpClient, to function. If you look at the code for the Elastic Search Sink you can see they pass in URI's but the sink creates the client itself - ElasticLowLevelClientnew HttpClientFactory()in the sink instead and call that to create your client?