4

I am using the relatively new ILogger (vs. TraceWriter) option in Azure functions and trying to understand how logs are captured.

Here's my function:

    public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, ILogger log)
    {
        log.LogTrace("Function 1 {level}", "trace");
        log.LogWarning("Function 1 {level}", "warning");
        log.LogError("Function 1 {level}", "error");

        return req.CreateResponse(HttpStatusCode.OK, "Success!!!!");
    }

When I look at the server logs, the LogFiles directory has a hierarchy.

enter image description here

The yellow highlighted file includes my log statements:

2017-08-19T13:58:31.814 Function started (Id=d40f2ca6-4cb6-4fbe-a05f-006ae3273562)
2017-08-19T13:58:33.045 Function 1 trace
2017-08-19T13:58:33.045 Function 1 warning
2017-08-19T13:58:33.045 Function 1 error
2017-08-19T13:58:33.075 Function completed (Success, Id=d40f2ca6-4cb6-4fbe-a05f-006ae3273562, Duration=1259ms)

The structured directory contains nothing here, but it seems to have various "codeddiagnostic" log statements in my real function applications directory.

What should I expect here? Ultimately, I would like to have a single sink for logging from all of my application components and take advantage of structured logging across the board.

Janusz Nowak
  • 2,595
  • 1
  • 17
  • 36
Jim O'Neil
  • 23,344
  • 7
  • 42
  • 67

3 Answers3

5

The best way to collect structured logging from Azure Functions is to use Application Insights. One you defined that your Logger is based on ILogger, you can define a Template that specifies the properties you want to log. Then on Application Insights traces, using the Application Insights Query Language (aka Kusto) you can access the values of each of these properties with the name customDimensions.prop__{name}.

You can find a sample of how to do this with Azure Functions v2 on this post https://platform.deloitte.com.au/articles/correlated-structured-logging-on-azure-functions

Paco de la Cruz
  • 2,066
  • 13
  • 22
  • Thank you for sharing such a detailed example. I really liked your approach to this, it helped me a lot – jokarl Oct 10 '22 at 15:54
5

Just FYI: Azure Functions running in isolated mode (.NET5 and .NET6) don't support structured logging using the ILogger from DI or provided in the FunctionContext. As of November 2021, there is an open bug about it: https://github.com/Azure/azure-functions-dotnet-worker/issues/423

As I understand it, the bug happens because all ILogger calls goes through the GRPC connection between the host and the isolated function, and in that process the message gets formatted instead of sending the original format and arguments. The Azure Insights connection that would record the structured log runs on the host and only receives the final message.

I plan on investigating some king of workaround, playing with direct access to Azure Insights inside the isolated process. If it works, I'll post the workaround in a comment at the bug linked above.

  • 1
    Ah thank you for this answer, I have been pulling my hair on why my logs aren't coming out structured. Do you have any updates on your workaround? – Mocas Sep 16 '22 at 16:21
2

I had the same question. The log file logger doesn't really respect structured logging, but if you use AppInsights for Azure Functions it will in fact add custom properties for your structured logging

I had a conversation going about it here https://github.com/Azure/azure-webjobs-sdk-script/issues/1675

Jeff
  • 35,755
  • 15
  • 108
  • 220