321X
321X

Reputation: 3185

Duplicate log entries in Application Insights with Isolated Azure Functions with ASP.NET Core Integration and Serilog

I have a .NET 8 Azure Functions project in an isolated worker process with ASP.NET Core Integration. For logging I want to use Serilog and the ApplicationInsights sink so I'm able to log scoped properties.

In my local settings I have APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING defined and my Program.cs looks like this:

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication(worker => {})
    .ConfigureAppConfiguration((hostingContext, configBuilder) =>
    {
        configBuilder.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true);
    })
    .ConfigureServices((hostBuilderContext, services) =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .UseSerilog((context, provider, configuration) =>
    {
        var telemetryClient = provider.GetRequiredService<TelemetryClient>();
       
        configuration
            .Enrich.WithMachineName()
            .Enrich.WithEnvironmentName()
            .Enrich.FromLogContext()
            .WriteTo.ApplicationInsights(telemetryClient, TelemetryConverter.Traces)
            .WriteTo.Console();
    })
    .Build();

await host.RunAsync();

host.json:

{
    "version": "2.0",
    "extensions": {
        "durableTask": {
            "storageProvider": {
                "type": "mssql",
                "connectionStringName": "EnterpriseResourcePlanningServicesDbConnection",
                "taskEventLockTimeout": "00:02:00",
                "createDatabaseIfNotExists": true,
                "schemaName": "dt"
            }
        }
    }
}

This results in duplicate logging (see image below) from my local development machine. What am I missing here? How is it possible that I get duplicate log entries? The one with [INF] isn't showing any scoped data under customDimensions where this is the case for the other log item (not showing on image)

I also tried to clear all the providers in ConfigureLogging on the host builder but no difference...

Example of duplicate log entry enter image description here

Upvotes: 0

Views: 410

Answers (1)

RithwikBojja
RithwikBojja

Reputation: 11363

The below code worked for me without generating Duplicate log entries:

Program.cs:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureAppConfiguration((ri_cxt, configBuilder) =>
    {
        configBuilder.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true);
    })
    .ConfigureServices((ri_cxt, ri_services) =>
    {
        IConfiguration ri_confg = ri_cxt.Configuration;
        ri_services.AddLogging(loggingBuilder =>
        {
            var con_strg = ri_confg["rith_con_str"];
            var ri_logconfg = new LoggerConfiguration()
                .MinimumLevel.Information()
                .Enrich.FromLogContext();
            ri_logconfg.WriteTo.ApplicationInsights(con_strg, TelemetryConverter.Traces);
            loggingBuilder.AddSerilog(ri_logconfg.CreateLogger());
        });
        ri_services.AddApplicationInsightsTelemetryWorkerService();
        ri_services.ConfigureFunctionsApplicationInsights();
    })
    .Build();
host.Run();

host.json:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "enableLiveMetricsFilters": true,
      "samplingSettings": {
        "isEnabled": false,
        "excludedTypes": "Request"
      }
    },
    "console": {
      "isEnabled": true,
      "logLevel": {
        "default": "Information"
      }
    }
  }
}

local.settings.json:

{
    "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "rith_con_str": "InstrumentationKey=4f7edc2b73;IngestionEndpoint=https://eastus-8.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/;ApplicationId=843db447-2af3-4597bc"
  }
}

Packages in csproj:

<ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.0" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
    <PackageReference Include="Serilog.Formatting.Compact" Version="2.0.0" />
    <PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" />
    <PackageReference Include="Serilog.Extensions.Logging" Version="3.0.2" />
    <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
</ItemGroup>

Function1.cs:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace FunctionApp191
{
    public class Function1
    {
        private readonly ILogger<Function1> ri_log;

        public Function1(ILogger<Function1> logger)
        {
            ri_log = logger;
        }

        [Function("Function1")]
        public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
        {
            ri_log.LogInformation("Hello Rithwik Bojja, Hope you are Rocking!!!");
            return new OkObjectResult("Function Executed!!!");
        }
    }
}

Output:

enter image description here

enter image description here

By following above program.cs and host.json and other code you will able to see only entries which you are logging and no duplicates are created.

Upvotes: 0

Related Questions