Each method in Azure Functions can have a Microsoft.Extensions.Logging.ILogger
injected into it for logging. Using WebJobsStartup
with a startup class you can change the logging to use Serilog using the following syntax:
[assembly: WebJobsStartup(typeof(Startup))]
namespace MyFuncApp {
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
builder.Services.AddLogging(
lb => lb.ClearProviders()
.AddSerilog(
new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File(@"C:\Temp\MyFuncApp.log")
.CreateLogger(),
true));
}
}
}
I can also add other objects to the DI and inject them either into the methods or into the constructor for the class containing the methods using i.e. builder.Services.AddSingleton<IMyInterface, MyImplementation>();
However, I would very much like to be able to inject the Microsoft.Extensions.Logging.ILogger
in the same way, but if I try to use the ILogger
in the constructor I get the following error during method invokation (as that's when the class is created):
Microsoft.Extensions.DependencyInjection.Abstractions: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'MyFuncApp.MyFunctions'.
So, is there any way of injecting the ILogger
into a class constructor like this?
public class MyFunctions
{
private IMyInterface _myImpl;
private ILogger _log;
public MyFunctions(
IMyInterface myImplememtation, // This works
ILogger log) // This does not
{
_myImpl = myImplementation;
_log = log;
_log.LogInformation("Class constructed");
}
public async Task<IActionResult> Function1([HttpTrigger() ... ) {
_log.LogInformation("Function1 invoked");
}
}
Serilog is a . NET library that provides diagnostic logging to files, the console, and almost everywhere you would like. Serilog can be used in classic . NET Framework applications and for applications running on the latest and greatest .
Serilog is a logging library for . NET and C# that allows for more detailed and structured logging than the default . NET logging library. Serilog can be used to log information about application events, errors, and performance metrics.
For example, if you are using Serilog you should configure Log. Logger and LibLog will use it. Also you can disable logging by setting LogProvider. IsDisabled to true . "
It is possible to further simplify the necessary setup by using the package Anotar.Serilog.Fody (and any other Anotar package for that matter)
You need to set up Serilog all the same in the Startup
class.
However, with the Fody
package you can completely get rid of the injected logger
using Anotar.Serilog;
public class Functions
{
[FunctionName("Token")]
public async Task<IActionResult> Function1(
[HttpTrigger()]...)
{
// static calls to the LogTo class
// get translated into proper Serilog code during build
LogTo.Information("Function1 invoked");
}
}
Please try the code below, it works at my side:
[assembly: WebJobsStartup(typeof(Startup))]
namespace MyApp
{
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
//other code
builder.Services.AddLogging();
}
}
public class Functions
{
//other code
private ILogger _log;
public Functions(ILoggerFactory loggerFactory)
{
_log = loggerFactory.CreateLogger<Functions>();
}
[FunctionName("Token")]
public async Task<IActionResult> Function1(
[HttpTrigger()]...)
{
_log.LogInformation("Function1 invoked");
}
}
}
With AzureFunctions v3, the pattern you outlined in your question works out-of-the box.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With