1

I am trying a fairly easy thing to do, but somehow I am missing something after all the Microsoft documents and SO posts I've been reading today.

I want to do some proper logging for my Azure Functions and all over the internet the best practice looks like it's Application Insights, but I've been struggling to get my AI to log my custom logs.

Here is my test function, if needed I can create a test project also.

Host.json

 {
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": false
      },
      "logLevel": {
        "default": "Information",
        "Minerva.Clocking": "Information"
      }
    }
  }
}

Startup.cs

    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
           
            ServiceProvider serviceProvider = builder.Services.BuildServiceProvider();
            Configurations.StaticConfig = serviceProvider.GetService<IConfiguration>();


            ConfigureServices(builder.Services);
        }

        private static void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IEmailService, EmailService>();

            services.AddHttpClient();
        }
    }

My test function

namespace Minerva.Clocking.Endpoints
{
    public class LoggingTestFunction
    {
        private readonly IEmailService m_EmailService;
        public LoggingTestFunction(IEmailService emailService)
        {
            m_EmailService = emailService;
        }

        [FunctionName("LoggingTestFunction")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation($"C# HTTP trigger function processed a request. Execution time: {DateTime.Now}");

        log.LogInformation("Info from function");
        log.LogWarning("Warning from function");
        log.LogError("Error from function");


        m_EmailService.LogSimpleMessage();
        m_EmailService.Foo();


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

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

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}

My EmailService

namespace Minerva.Clocking.Services
{
    public class EmailService : IEmailService
        {
            private readonly HttpClient m_httpClient;
            private readonly ILogger<EmailService> m_EmailLogger;
            public EmailService(IHttpClientFactory httpClientFactory, ILogger<EmailService> logger)
            {
                m_httpClient = httpClientFactory.CreateClient();
                m_EmailLogger = logger;
            }
    
            public void LogSimpleMessage()
            {
                m_EmailLogger.LogInformation("This is a information to be seen in azure");
                m_EmailLogger.LogError("This is a error to be seen in azure");
                m_EmailLogger.LogWarning("This is a warning to be seen in azure");
            }



 public void Foo()
        {
            m_EmailLogger.LogInformation("Foo");
            m_Telemetry.TrackTrace("BarLog", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information);
            m_Telemetry.TrackEvent("BarEvent");
        }
    }
}

Whenever I look into the AI logs in azure all I see is the message logged inside the function itself and nothing from my EmailService

enter image description here

Most likely I am missing something, but I am not sure what, can someone point me to a documentation or something that could allow me to log everything that is inside my Azure Function in AI?

I would also like to be able to see the logs in console, but I couldn't find any relevant information about that either on the internet (I know I am a bad searcher).

Thank you

Edit : Updated the code to include ClientTelemetry. The log from telemetry I can see in Azure, but still no logs from ILogger.

CiucaS
  • 2,010
  • 5
  • 36
  • 63
  • 1) You should remove the statement `builder.Services.AddLogging()` as Azure function by default adds the default logger; so you won't be require that injection. 2) You can set the `isEnabled` to false of `samplingSettings` (of `applicationInsights`) – user1672994 Jul 21 '21 at 10:52
  • 2
    Also in query, try to find the log using message and check if the logged message is part of same operation_name.... I believe operation_Id should match but not sure about operation_name. – user1672994 Jul 21 '21 at 10:56
  • @user1672994 I've updated my Startup.cs class and host.json. Searched for message using containts, but no luck. I've also added TelemetryClient and logged a message via TelemetryClient and that works, only the ones from Logger do not show up. – CiucaS Jul 21 '21 at 11:11
  • You might already had `APPINSIGHTS_INSTRUMENTATIONKEY` settings defined in functions app-settings. but what to confirm if it exist? – user1672994 Jul 23 '21 at 04:38
  • Also, are you using the latest SDK package (I believe you are using V3). Also do you have nuget package reference of `Microsoft.ApplicationInsights`? If yes, then what is the version of that? – user1672994 Jul 23 '21 at 04:39
  • @user1672994 yes the APPINSIGHTS_INSTRUMENTATIONKEY is present in configuration ( as you can see some of the logs work). Microsoft.NET.Sdk.Functions 3.0.11 and Microsoft.ApplicationInsights 2.17 . This are my versions. Function runs on .NET Core 3.1 – CiucaS Jul 23 '21 at 08:21
  • Log Categories (or "Source", ie. the name of the class injected into) are added as custom dimensions to the traces. Only the main function logger (which is different from DI injected ILogger<>) will have the operation_name. As noted above though, the operation_id *should* match. There's also a custom dimension for the function execution Id that should match as well. Try finding messages by using the Source and/or Category custom dimensions *only* and not the operation name. Then you can backtrack from there to figure out how to correlate – pinkfloydx33 Jul 24 '21 at 21:18

1 Answers1

0

I believe the problem is in your host.json. Try the following:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true
      },
      "logLevel": {
        "Minerva.Clocking.Endpoints.LoggingTestFunction": "Information"
      }
    }
  }
} 

source: https://github.com/jeffhollan/functions-csharp-custom-ilogger and https://github.com/Azure/Azure-Functions/issues/1484#issuecomment-594914999

Thiago Custodio
  • 17,332
  • 6
  • 45
  • 90