Search code examples
c#azuredependency-injectionazure-functionsserilog

Serilog in Azure Functions


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");
    }
}

Solution

  • 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");
            }
        }
    
    }