0

I am trying to add a customDimension to my Azure Function logs but they don't seem to be coming through and I have no idea why. I have tried using BeginScope and sending the args with the individual logs but neither seems to work.

 public static void LogCustomTrace(this ILogger logger,
            string method,
            string message,
            TraceType traceType,
            LogLevel logLevel = LogLevel.Information,
            Exception? exception = null,
            params object[] args)
        {
            var customProperties = new Dictionary<string, object>
            {
                ["TraceType"] = traceType.ToString()
            };

            using (logger.BeginScope(customProperties))
            {
                if (exception != null)
                {
                    logger.Log(logLevel, exception, $"[{method}]: {message}", args);
                }
                else
                {
                    logger.Log(logLevel, $"[{method}]: {message}", args);
                }
            }
        }

and

public static void LogCustomTrace(this ILogger logger,
            string method,
            string message,
            TraceType traceType,
            LogLevel logLevel = LogLevel.Information,
            Exception? exception = null,
            params object[] args)
        {
            var customProperties = new Dictionary<string, object>
            {
                ["TraceType"] = traceType.ToString()
            };

            if (exception != null)
            {
                logger.Log(logLevel, exception, $"[{method}]: {message}", customProperties);
            }
            else
            {
                logger.Log(logLevel, $"[{method}]: {message}", customProperties);
            }
        }

I have found some threads where people have managed to add customDimensions but for all logs for the same request - I just want to do it for a single log and each log will have a different type so they can be easily filtered.

The function app is set up like so:

 .ConfigureServices((hostContext, services) =>
 {
     services.AddApplicationInsightsTelemetryWorkerService();
     services.ConfigureFunctionsApplicationInsights();

and I'm using the up to date Microsoft.ApplicationInsights.WorkerService and Microsoft.Azure.Functions.Worker.ApplicationInsights pacakges.

3
  • Have you got any error? what is the .net version and function model? Commented Nov 6, 2024 at 13:10
  • @DasariKamali nope, no errors and the logs are recorded correctly under logs just without the customDimensions! .Net 8.0 with Azure Function in isolated worker mode Commented Nov 6, 2024 at 15:20
  • I can see the Custome Dimension in application insights logs. Commented Nov 8, 2024 at 2:40

1 Answer 1

1

I tried the below Http trigger Function Isolated model to get the Custom Dimensions for the Azure Function app using Application Insights.

Helpers/LoggerExtensions.cs :

using FunctionApp24.Functions;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.Extensions.Logging;
using System;

namespace FunctionApp24.Helpers
{
    public static class LoggerExtensions
    {
        public static void LogCustomTrace(this TelemetryClient telemetryClient,
                                          string method,
                                          string message,
                                          TraceType traceType,
                                          LogLevel logLevel = LogLevel.Information,
                                          Exception? exception = null)
        {
            var traceTelemetry = new TraceTelemetry
            {
                Message = $"[{method}]: {message}",
                SeverityLevel = logLevel.ToSeverityLevel()
            };
            traceTelemetry.Properties["TraceType"] = traceType.ToString();
            if (exception != null)
            {
                traceTelemetry.Properties["ExceptionType"] = exception.GetType().Name;
                traceTelemetry.Properties["ExceptionMessage"] = exception.Message;
            }

            telemetryClient.TrackTrace(traceTelemetry);
        }

        public static SeverityLevel ToSeverityLevel(this LogLevel logLevel)
        {
            return logLevel switch
            {
                LogLevel.Trace => SeverityLevel.Verbose,
                LogLevel.Debug => SeverityLevel.Verbose,
                LogLevel.Information => SeverityLevel.Information,
                LogLevel.Warning => SeverityLevel.Warning,
                LogLevel.Error => SeverityLevel.Error,
                LogLevel.Critical => SeverityLevel.Critical,
                _ => SeverityLevel.Information
            };
        }
    }
}

Functions/MyFunction.cs :

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using Microsoft.ApplicationInsights;
using System.Net;
using FunctionApp24.Helpers;

namespace FunctionApp24.Functions
{
    public class MyFunction
    {
        private readonly ILogger<MyFunction> _logger;
        private readonly TelemetryClient _telemetryClient;

        public MyFunction(ILogger<MyFunction> logger, TelemetryClient telemetryClient)
        {
            _logger = logger;
            _telemetryClient = telemetryClient;
        }

        [Function("MyFunction")]
        public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
        {
            _logger.LogInformation("Function MyFunction triggered");
            _telemetryClient.LogCustomTrace("MyFunction", "Processing request", TraceType.Request);
            var response = req.CreateResponse(HttpStatusCode.OK);
            await response.WriteStringAsync("Function executed successfully.");
            return response;
        }
    }
    public enum TraceType
    {
        Request,
        Response,
        Error
    }
}

appsettings.json :

{
    "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<storageconnec>",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "APPLICATIONINSIGHTS_CONNECTION_STRING": "<connecstring>"
  }
}

Publish the above project to the Azure Function App and run it in the Azure Portal like below.

enter image description here

Query :

Run the below query in the Azure Application Inisghts > Logs to get the Cunstome Dimensions for the Function app.

traces
| where customDimensions.TraceType == "Request"
| project timestamp, message, customDimensions
| order by timestamp desc

Custome Dimensions Output :

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks that works but it then doesn't log to the console and then if I add another ILogger then in app insights I get two logs in App Insights. The thing I'm seeking to understand is why the Ilogger in app insights is ignoring my custom properties
To ensure your custom dimensions appear in ILogger logs without duplicating entries, you can configure the ILogger to use the same TelemetryClient by injecting and handling them together. This way, both ILogger and TelemetryClient will log your custom properties seamlessly without double entries.
Unfortunately I don't understand what that means?

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.