4

At the moment I'm trying to add an ILogger or ILogger<> to a Azure Durable Function so as to use logging in Activity Functions.

Logging in the Orchestration Function works fine and is injected in the method itself, but attempts at constructor injection for ILogger always results in a Null Exception.

builder.Services.AddLogging();

The above does not seem to work when added to the Startup file (Bootstrapper) and neither does variations on:

builder.Services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));

Anyone solved this?

3
  • Are you trying to inject the logger into a different class? Commented Nov 7, 2019 at 16:31
  • I have indeed @chris. I think it's a limitation of Activity functions where the logging may need to be passed in using a tuple or otherwise. Commented Nov 7, 2019 at 16:32
  • According to this, "The host injects ILogger<T> and ILoggerFactory services into constructors. However, by default these new logging filters are filtered out of the function logs. You need to modify the host.json file to opt-in to additional filters and categories. Commented May 12, 2022 at 20:11

1 Answer 1

4

Remove either of these lines from your Startup file:

builder.Services.AddLogging();
builder.Services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));

Then, wherever you are injecting your ILogger, add the type that your logger is being injected into using ILogger<T> i.e:

public class Function1
{
    private readonly ILogger _logger;

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

    [FunctionName("Function1")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
    {
        _logger.LogInformation("C# HTTP trigger function processed a request.");

        string name = req.Query["name"];

        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;

        return name != null
            ? (ActionResult)new OkObjectResult($"Hello, {name}")
            : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

I believe logging is added by default so your first suggestion about removing the registration was accurate.
Thanks for your response @chris, this does not work though and is something I'd already tried. Bare in mind, this is Durable Functions and not stateless Azure Functions.
@BillyRayValentine Did you ever find a solution to this?
I didn't, in the end the ILogger was passed in the function as opposed to the constructor, which is not ideal but is still the correct logger bootstrapped by the framework.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.