Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET 8 Azure Function App getting ILogger=NULL

I'm pushing my first .NET 8 Function App out to Azure and I'm getting an error that the ILogger is NULL. I'm following the same code as I've used before on .NET 6. It also works as expected when I run the app locally on my development machine.

Is there a setting that I might be missing to get this to work?

public class StorageUtilityHandler
{
    private readonly ILogger<StorageUtilityHandler> _logger;
    private readonly IBusinessLogic _businessLogic;

    public StorageUtilityHandler(ILogger<StorageUtilityHandler> logger, IBusinessLogic businessLogic)
    {
         _logger = logger;
         _businessLogic = businessLogic;
    }

    [Function("LogProcessorQueue")]
    public static Task ProcessLogQueueAsync(
        [ServiceBusTrigger("%LogServiceBusQueue%", Connection = "ServiceBusConnection")] string logFileMessage, ILogger log)
    {
        if (logFileMessage != null)
        {
            try
            {
                LogEntity? logEntity = JsonSerializer.Deserialize<LogEntity>(logFileMessage);
                    
                if (logEntity != null)
                {
                    // If ERROR then send out Email 
                    if (logEntity.Message.Contains("ERROR")) 
                    {
                        var _email = new EmailService();
                        _email.SendLogError(logEntity);
                    }

                    var storageConnection = Environment.GetEnvironmentVariable("StorageConnection");
                    var loggingTableName = Environment.GetEnvironmentVariable("LoggingTableName");

                    TableClient tableClient = new(storageConnection, loggingTableName);

                    // Create the table if it doesn't already exist to verify we've successfully authenticated.
                    tableClient.CreateIfNotExists();        //Remove in PROD

                    tableClient.AddEntity(logEntity);
                }
            }
            catch (Exception ex)
            {
                log.LogError($"Error processing Log message. {ex.Message} | {ex.StackTrace} | {ex.InnerException}");
            }
        }

        return Task.CompletedTask;
    }
}

Program.cs:

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();

        services.AddTransient<IBusinessLogic, BusinessLogic>();
    })
    .Build();

All my Service Bus messages from this FA are going into the Dead Letter queue. Looking at the messages in the Dead Letter queue, they look correct. When I look at the logs from Application Insights, I get the following error about ILogger being NULL.

Operation_Name: LogProcessorQueue

Exception: System.ArgumentNullException: Value cannot be null. (Parameter 'logger')

at System.ThrowHelper.Throw(String paramName)
at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, String message, Object[] args)
at Microsoft.Extensions.Logging.LoggerExtensions.LogError(ILogger logger, String message, Object[] args)

like image 930
Caverman Avatar asked Apr 08 '26 00:04

Caverman


2 Answers

From my observations, the Functions runtime doesn't inject the non-generic ILogger into method calls anymore, and hasn't for some time; I have observed .NET 6 implementations of this ceasing to work, so it's surprising that you have found that it does. You have two references to a logger in your code, so if you were to switch to using the correctly-injected generic ILogger<T> to log in your catch block, that should fix the error you're seeing. The failure to log is in my view expected behaviour given the dependency on the log method argument that is no longer supported.

Edit:

Having said that, this question and its answers look more likely. I might have misinterpreted the errors I was seeing when I converted all the functions I've worked on to use constructor-injected ILogger, and that fixes the problem.

like image 93
Tom W Avatar answered Apr 10 '26 14:04

Tom W


Logger needs to be implemented using DI, no need to add any configuration unless a custom logger is needed and remove ILogger log from function. Logger is automatically injected.

   private readonly ILogger<GetHelp> _logger;

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

   [Function("GetHelp")]
   public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
   {
like image 26
JSP Avatar answered Apr 10 '26 15:04

JSP



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!