Reputation: 675
I'm using Azure Functionapp (version 4) isolated worker process. I have configured Serilog in the program.cs file as below. But in my actual function when I inject Serilog.ILogger
, it fails with error during runtime, unable to resolve Serilog.ILogger
.
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Microsoft.Azure.Functions.Worker;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
s.AddApplicationInsightsTelemetryWorkerService();
s.ConfigureFunctionsApplicationInsights();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("Application", "Application")
.Enrich.WithProperty("Environment", "Dev")
.MinimumLevel.Warning()
.WriteTo.ApplicationInsights(TelemetryConfiguration.CreateDefault(), TelemetryConverter.Traces)
.CreateLogger();
//configure seriLog
s.AddLogging(lb =>
{
lb.AddSerilog(Log.Logger, true);
});
s.Configure<LoggerFilterOptions>(options =>
{
// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
// Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs
LoggerFilterRule toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (toRemove is not null)
{
options.Rules.Remove(toRemove);
}
});
})
.Build();
host.Run();
I Also tried using the below method to register Serilog but its still fails -
s.AddSingleton<ILoggerProvider>((sp) =>
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.ApplicationInsights(sp.GetRequiredService<TelemetryClient>(), TelemetryConverter.Traces)
.CreateLogger();
return new SerilogLoggerProvider(Log.Logger, true);
});
Upvotes: 0
Views: 774
Reputation: 2466
The main reason that Serilog.ILogger
is not resolvable is that AddSerilog
doesn't add Serilog.ILogger
as a resolvable service as you shouldn't be requesting a Serilog.ILogger
.
The AddSerilog
that you are using is an extension method to Microsoft.Extensions.Logging.ILoggingBuilder
and it adds Serilog as an ILoggerProvider
(see source code). That way, when you request an Microsoft.Extensions.Logging.ILogger
, it will build an logger that logs to all the registered ILoggerProvider
s as Serilog may not be the only provider.
Instead, you should be requesting that an Microsoft.Extension.Logging.ILogger<T>
be injection into your function.
If you really want an Serilog.ILogger
injected, then you need to use extension AddSerilog
on the IServiceCollection
and provide Log.Logger
. The source code for that function is here.
You should be using any of the following:
var host = new HostBuilder()
.UseSerilog()
.Build()
// OR
var host = new HostBuilder()
.ConfigureServices(s =>
{
s.AddSerilog();
})
.Build();
// OR
var host = new HostBuilder()
.ConfigureServices(s =>
{
s.ConfigureLogging(lb => lb.AddSerilog());
})
.Build();
and then injecting ILogger<T>
is the recommended practice since your functions shouldn't know anything about Serilog. You also never need to specify Serilog's static Log.Logger
as it will be used by default if ILogger is not specified.
And here's what you should do if you want to inject a Serilog.ILogger
.
var host = new HostBuilder()
.ConfigureServices(s =>
{
s.AddSerilog(Log.Logger);
})
.Build();
I didn't specify whether you need to use dispose or not, that's up to your implementation.
Upvotes: 2