Search code examples
c#azureazure-functionsazure-application-insightsmicrosoft-extensions-logging

Application Insights not logging with Azure Functions C#. Namespace seems the problem


Our function delegates all the logic to another class "CreateHandler" where we use the ILogger through DI. The function logs properly but the CreateHandler does not. Locally we verified that it does not log to the console, UNLESS we change the class namespace to something that starts with "Function". That means that FunctionR or FunctionS will work but RFunction or SFunction won't. We are dealing with that class and a service. Clearly our service has a completely different namespace and we would need to keep that one, while logging at the same time. How can we make the class log without changing the namespace?

CreateHandler class (logging right):

using ExampleProject.Domain.Entities;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace FunctionAnything
{
    public class CreateHandler
    {
        private readonly ILogger<CreateHandler> _logger;

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

        public async Task Handle(Car car)
        {
            _logger.LogInformation($"This is logging properly");
        }
    }
}

CreateHandler class (not logging):

using ExampleProject.Domain.Entities;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace ExampleProject.Functions.Handlers
{
    public class CreateHandler
    {
        private readonly ILogger<CreateHandler> _logger;

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

        public async Task Handle(Car car)
        {
            _logger.LogInformation($"This is not logging");
        }
    }
}

Startup:

using ExampleProject.Functions.Handlers;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(ExampleProject.Functions.Startup))]
namespace ExampleProject.Functions
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<CreateHandler>();
        }
    }
}

Function:

using ExampleProject.Domain.Entities;
using ExampleProject.Functions.Handlers;
using ExampleProject.Service.Constants;
using Microsoft.Azure.WebJobs;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace ExampleProject.Functions
{
    public class Function
    {
        private readonly CreateHandler _createHandler;

        public Function(
            CreateHandler createHandler)
        {
            _createHandler = createHandler;
        }
        
        [FunctionName("Create")]
        public async Task Create([QueueTrigger(QueueNames.Create)] Car car)
        {
            log.LogInformation("I'm logged");
            await _createHandler.Handle(car);
        }
    }
}

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true"
  }
}

host.json:

{
  "version": "2.0",
}

Solution

  • I noticed this issue in github before(if the namespace is not started with Function), but currently cannot find it.

    The solution is that, you should add the completed namespace+class name in host.json if the namespace is not started with Function. Like below:

    {
      "version": "2.0",
      "logging": {
        "logLevel": {
          "ExampleProject.Functions.Handlers.CreateHandler": "Information"
        }
      }
    }
    

    Or a general way:

    "logLevel": { "Default": "Information" }