Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Functions Dependency Tracking for SQL Server and Service Bus Into Application Insights

Previously I have Azure Web App (.net core) and It successfully track the SQL Server and Service Bus dependency into Application Insights. It is not working some how with Azure Functions.

Environment

  • dotnet 6
  • dotnet-isolated mode
  • log level default set to "Information".
  • Azure Environment using Consumption plan for Azure Functions.
  • Application Insights key is configured.

I have Azure API management at front and backend is Azure Function and that call SQL Server and Service Bus.

  • Api Management Service to Azure function dependency successfully resolved but Azure Function to other component is not working.
like image 287
dotnetstep Avatar asked Dec 29 '25 16:12

dotnetstep


2 Answers

I know I am posting my own answer. Also there are chance that in future there may be some good solution or it get integrated the way it is in in-process mode.

By then follow steps.

  1. Add Package
Microsoft.ApplicationInsights.WorkerService
  1. In program.cs in configuring host.
services.AddApplicationInsightsTelemetryWorkerService();

More info at https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service

like image 160
dotnetstep Avatar answered Jan 01 '26 09:01

dotnetstep


The only way I've managed to solve this issue so far was by setting up custom Middleware

.ConfigureFunctionsWorkerDefaults(config =>
{
    config.UseMiddleware<AiContextMiddleware>();
})

In the IServiceCollection you need to setup simply

.AddApplicationInsightsTelemetryWorkerService()

public class AiContextMiddleware : IFunctionsWorkerMiddleware
{
    private readonly TelemetryClient _client;
    private readonly string _hostname;

    public AiContextMiddleware(TelemetryClient client)
    {
        _client = client;
        _hostname = Environment.GetEnvironmentVariable("AI_CLOUD_ROLE_NAME");
    }

    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        var operationId = ExtractOperationId(context.TraceContext.TraceParent);
        
        // Let's create and start RequestTelemetry.
        var requestTelemetry = new RequestTelemetry
        {
            Name = context.FunctionDefinition.Name,
            Id = context.InvocationId,
            Properties =
            {
                { "ai.cloud.role", _hostname},
                { "AzureFunctions_FunctionName", context.FunctionDefinition.Name },
                { "AzureFunctions_InvocationId", context.InvocationId },
                { "AzureFunctions_OperationId", operationId }
            },
            Context =
            {
                Operation =
                {
                    Id = operationId,
                    ParentId = context.InvocationId,
                    Name = context.FunctionDefinition.Name
                },
                GlobalProperties =
                {
                    { "ai.cloud.role", _hostname},
                    { "AzureFunctions_FunctionName", context.FunctionDefinition.Name },
                    { "AzureFunctions_InvocationId", context.InvocationId },
                    { "AzureFunctions_OperationId", operationId }
                }
            }
        };

        var operation = _client.StartOperation(requestTelemetry);

        try
        {
            await next(context);
        }
        catch (Exception e)
        {
            requestTelemetry.Success = false;
            _client.TrackException(e);

            throw;
        }
        finally
        {
            _client.StopOperation(operation);
        }
    }

    private static string ExtractOperationId(string traceParent)
        => string.IsNullOrEmpty(traceParent) ? string.Empty : traceParent.Split("-")[1];
}

It's definitely not a perfect solution as you then get two starting logs, but as end result, you get all logs traces + dependencies correlated to an operation.

I've solved this issue in the first place like that, now I'm revisiting whether there are any better ways to solve this.

Let me know too whether you managed to solve this issue on your side.

like image 39
Mateusz Szuta Avatar answered Jan 01 '26 08:01

Mateusz Szuta



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!