У меня есть приложение Azure Function в .NET 6, я использую Microsoft.Extension.Logging для ведения журнала, и все работает отлично.
Теперь у меня появилось новое требование по поддержке структурированного ведения журналов, поэтому я решил использовать Serilog, но после настройки журналы Serilog регистрируются дважды в Application Insights.
Это моя startup.cs конфигурация для Serilog
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...
}
Если я удалю приведенный ниже код из startup.cs, он не будет записываться дважды, и будут показаны только журналы Serilog, но я не смогу удалить этот код, так как мне также нужен специальный процессор телеметрии.
По сути, когда я регистрирую собственный процессор телеметрии, он также активирует Microsoft Logger, и поэтому я получаю журналы в два раза больше, чем я занижал.
// 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();
Как я могу зарегистрировать собственный процессор телеметрии в Serilog, не активируя регистратор Microsoft?


Журналы Serilog регистрируются дважды в Application Insights.
Код ниже работал у меня и записывал только необходимые журналы, дубликатов не было:
Функция1.cs:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
namespace FunctionApp16
{
public class Function1
{
private readonly Rith_Logger<Function1> rith_lg;
public Function1(Rith_Logger<Function1> logger)
{
rith_lg = logger;
}
[FunctionName("Function1")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
{
rith_lg.LogInformation("Hello Rithwik Bojja !!!");
var rith_obj = new { Weight = 60, Height = 170 };
var rith_e = 24;
rith_lg.LogInformation("Hello the structered log is {@rith_obj} in {rith_e} age", rith_obj, rith_e);
return new OkObjectResult("Hello Rithwik Bojja !!!");
}
}
}
хост.json:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"enableLiveMetricsFilters": true,
"samplingSettings": {
"isEnabled": false,
"excludedTypes": "Request"
}
},
"console": {
"isEnabled": true,
"logLevel": {
"default": "Information"
}
}
}
}
Здесь для параметра SampleSettings установлено значение false.
Стартап.cs:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Serilog;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.DependencyCollector;
using Microsoft.Extensions.Logging;
using Microsoft.ApplicationInsights.Channel;
[assembly: FunctionsStartup(typeof(FunctionApp16.Startup))]
namespace FunctionApp16
{
internal class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var rith_tc = TelemetryConfiguration.CreateDefault();
rith_tc.ConnectionString = "InstrumentationKey=af34a9dc-f1df-4ff8-9ac9-6c1f0401ef4c;IngestionEndpoint=https://eastus-8.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/;ApplicationId=ff7a6";
var rith_dm = new DependencyTrackingTelemetryModule();
rith_dm.Initialize(rith_tc);
var rit_tpb = rith_tc.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
var rih_conf = builder.Services.BuildServiceProvider().GetService<IConfiguration>();
rit_tpb.Use(next => new CustomTelemetryProcessor(next, rih_conf));
rit_tpb.Build();
Log.Logger = new LoggerConfiguration()
.WriteTo.ApplicationInsights(rith_tc, TelemetryConverter.Traces)
.CreateLogger();
builder.Services.AddSingleton(rith_tc);
builder.Services.AddSingleton(typeof(Rith_Logger<>), typeof(AppLogger<>));
builder.Services.AddLogging(loggingBuilder =>
{
loggingBuilder.AddSerilog(Log.Logger, dispose: true);
});
}
}
public class CustomTelemetryProcessor : ITelemetryProcessor
{
private ITelemetryProcessor Next { get; set; }
private readonly IConfiguration rith_conf;
public CustomTelemetryProcessor(ITelemetryProcessor next, IConfiguration configuration)
{
Next = next;
rith_conf = configuration;
}
public void Process(ITelemetry rit)
{
Next.Process(rit);
}
}
public interface Rith_Logger<T>
{
void LogInformation(string rith_ms, object rith_po, int rith);
void LogInformation(string rith_ms);
}
public class AppLogger<T> : Rith_Logger<T>
{
private readonly ILogger<T> rith_lg;
public AppLogger(ILogger<T> logger)
{
rith_lg = logger;
}
public void LogInformation(string rith_ms, object rith_po, int rith)
{
rith_lg.LogInformation(rith_ms, rith_po, rith);
}
public void LogInformation(string rith_ms)
{
rith_lg.LogInformation(rith_ms);
}
}
}
Выход:

Мои пакеты в csproj:
<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>
Галд, это сработало @Shri
Это сработало, спасибо @RithwikBojja :), похоже, проблема была в настройке host.json, в остальном все было хорошо.