Search code examples
c#azure-functionsazure-application-insights.net-6.0azure-functions-runtime

See multiple ways to obtain ILogger in Azure Functions 6 from docs and templates, what are the differences?


I'm using Azure Functions 6 (.NET 6, isolated), with Application Insights enabled.

From different versions of Visual Studio, Azure Functions Core Tools, the default Microsoft templates and other docs showed a variety of ways to obtain ILogger. I've seen:

  1. Constructor injection of ILoggerFactory (from a default MS template):
private readonly ILogger _logger;

public MyFunction(ILoggerFactory loggerFactory)
{
    _logger = loggerFactory.CreateLogger<MyFunction>();
}
  1. Getting it from the FunctionContext (also from default MS template):
public async Task<HttpResponseData> Run([HttpTrigger(...)] HttpRequestData req, FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("MyFunction);
}
  1. Injecting ILogger directly into the Run method:
public static void Run(EventGridEvent eventGridEvent, ICollector<string> outputSbMsg, ILogger logger)

  1. Regular ASP.NET Core constructor injection of ILogger<T>:
private readonly ILogger<MyFunction> _logger;

public MyFunction(ILogger<MyFunction> logger)
{
    _logger = logger;
}

What are the differences of all these methods and which ones are the best to use?


Solution

  • 4. Regular ASP.NET Core constructor injection of ILogger<T>:

    private readonly ILogger<MyFunction> _logger;
    public MyFunction(ILogger<MyFunction> logger)
    {
        _logger = logger;
    }
    
    • It is the most preferable way to use Logger in your project.
    • Using a logger in your project depends on your need.
    • In the above way, you can use where ever you want to use the logger in your code.
    • If you are using a smaller function project you can use whatever methods you want. But when it comes to Large function Projects obviously we were using multiple classes so everywhere creating a logger is more complicated. So using this constructor we can use where ever we want just calling the constructor to log your telemetry.

    3. Injecting ILogger directly into the Run method:

    public static void Run(EventGridEvent eventGridEvent, ICollector<string> outputSbMsg, ILogger logger)
    

    In this way, we can access the logger inside the specific Run method. outer Run it is not able to access.

    2. Getting it from the FunctionContext (also from default MS template):

    public async Task<HttpResponseData> Run([HttpTrigger(...)] HttpRequestData req, FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger("MyFunction);
    }
    

    Which is similar to the 3rd point. But the difference between 2nd and 3rd was using Execution context. The Execution context contains the function information so we can get the details of the functions in an Execution context.

    1. Constructor injection of ILoggerFactory (from a default MS template):

    private readonly ILogger _logger;
    public MyFunction(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<MyFunction>();
    }
    

    Here ILoggerFactory is brings together all the collections of ILoggerProviders, and the ILoggerFactory creates ILogger<T> instances for the application. It contains ILogger, ILogger<T>, ILoggerProvider and ILoggerFactory. so using this we can use the all usages of ILogger.

    Either you can use the 1st or 4th approach which is the effective way to use ILogging.