Serilog 结构化日志在使用 .NET 6 和 Application Insights 的 Azure Function 中无法按预期工作

问题描述 投票:0回答:1

我有一个在 .NET 6 上运行的 Azure Function App,我使用

Microsoft.Extension.Logging
进行日志记录,一切都运行良好。

现在我有一个支持结构化日志记录的新需求,因此我决定使用 Serilog,但即使完成所有配置后,结构化日志也没有按预期显示在应用程序洞察中。

这是我的 Serilog

startup.cs
配置:

public override void Configure(IFunctionsHostBuilder builder)
{
    var telemetryConfiguration = TelemetryConfiguration.CreateDefault();
    telemetryConfiguration.ConnectionString = Settings.ApplicationInsightsConnectionString;

    // Create and initialize the dependency tracking module
    var dependencyModule = new DependencyTrackingTelemetryModule();
    dependencyModule.Initialize(telemetryConfiguration);

    // Create the custom telemetry processor
    var telemetryProcessorChainBuilder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
    var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>();

    telemetryProcessorChainBuilder.Use(next => new CustomTelemetryProcessor(next, configuration));

    // Build the telemetry processor chain
    telemetryProcessorChainBuilder.Build();

    Log.Logger = new LoggerConfiguration()
                           .WriteTo.ApplicationInsights(telemetryConfiguration, TelemetryConverter.Traces)
                           .CreateLogger();

    builder.Services.AddSingleton(telemetryConfiguration);
    builder.Services.AddSingleton(typeof(IAppLogger<>), typeof(AppLogger<>));
  
    // rest of the code...
}

这是我使用

AppLogger
记录的日志,它使用
Microsoft.Extension.Logging
:

_logger.LogInformation("Log message {@LogMessage}", new LogMessage { ApplicationName = ApplicationDetails.ApplicationName, MethodName = AzureFunctionNames.Function1, IngressEvent = inputMessage.Payload.EventBody });

它以

LogMessage
的序列化 JSON 形式记录在 Application Insight 中,而不是以结构化日志格式记录,以便我应该能够查询
LogMessage
类的每个实体。

我无法在 Application Insights 中查看结构化日志的原因可能是什么?

提供Function App项目包及版本,

<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="5.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.22.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.60.3" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.3" />
<PackageReference Include="Serilog" Version="3.1.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Formatting.Compact" Version="2.0.0" />
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="3.1.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
azure-functions .net-6.0 azure-application-insights serilog structured-logging
1个回答
0
投票

我已经使用运行时堆栈.NET 6.0版本创建了Http触发功能,并在Startup.cs中配置了Serilog和应用程序洞察。

函数1.cs:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace FunctionApp490028
{
    public class Function1
    {
        private readonly ILogger<Function1> _logger;

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

        [FunctionName("Function1")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            _logger.LogInformation("Hello pavan");

            var Obj = new { Weight = 60, Height = 170 };
            var Obj1 = 24;

            _logger.LogInformation("Hello the structured log is {@Obj} in {Obj1} age", Obj, Obj1);

            return new OkObjectResult("Hello pavan");
        }
    }
}

Startup.cs

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.DependencyCollector;
using Microsoft.Extensions.Logging;
using Microsoft.ApplicationInsights.Channel;

[assembly: FunctionsStartup(typeof(FunctionApp490028.Startup))]

namespace FunctionApp490028
{
    internal class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // Configure Application Insights
            var telemetryConfiguration = TelemetryConfiguration.CreateDefault();
            telemetryConfiguration.ConnectionString = "Your Appinsights conn-string";

            // Enable Dependency Tracking Telemetry Module
            var dependencyModule = new DependencyTrackingTelemetryModule();
            dependencyModule.Initialize(telemetryConfiguration);

            // Custom Telemetry Processor
            var telemetryProcessorChainBuilder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
            telemetryProcessorChainBuilder.Use(next => new CustomTelemetryProcessor(next));
            telemetryProcessorChainBuilder.Build();

            // Configure Serilog
            Log.Logger = new LoggerConfiguration()
                .WriteTo.ApplicationInsights(telemetryConfiguration, TelemetryConverter.Traces)
                .CreateLogger();

            // Add Serilog to Logging
            builder.Services.AddLogging(loggingBuilder =>
            {
                loggingBuilder.AddSerilog(Log.Logger, dispose: true);
            });

            // Register services
            builder.Services.AddSingleton(telemetryConfiguration);
            builder.Services.AddSingleton(typeof(ILogger<>), typeof(ILogger<>));
        }
    }

    public class CustomTelemetryProcessor : ITelemetryProcessor
    {
        private readonly ITelemetryProcessor _next;

        public CustomTelemetryProcessor(ITelemetryProcessor next)
        {
            _next = next;
        }

        public void Process(ITelemetry item)
        {
            _next.Process(item);
        }
    }
}

.cs 项目:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
      <PackageReference Include="Microsoft.ApplicationInsights" Version="2.22.0" />
      <PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.22.0" />
      <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
      <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.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>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

通过使用上述包和代码能够在应用程序洞察中成功获取结构化日志。检查以下:

输出:

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.