Трассировка Serilog — Azure Monitor с трассировками и несовпадающими интерваламиC#

Место общения программистов C#
Ответить
Anonymous
 Трассировка Serilog — Azure Monitor с трассировками и несовпадающими интервалами

Сообщение Anonymous »

Наше решение для ведения журнала и трассировки в нашем веб-API ASP.NET Core 8 использует SerilogTracing и Azure Monitor.
Следуя последним советам из этой статьи, мы видим промежутки/трассировки для запускаемых действий.
https://nblumhardt.com/2024/04/serilog-net8-0-minimal/
Однако временная шкала в представлении операций App Insights и то, где эти трассировки попадают во время существования HTTP-запроса .NET, не совпадают. При фильтрации компонента действия SerilogTracing не отображаются. Но без фильтрации следы операции существуют.
Просмотр временной шкалы в App Insights
Пример несвязанной трассировки (дочернее действие)
Действие контроллера, трассировка существует в фильтре компонентов (действие контроллера)
Изображение текущего поведения в надежде выровнять иерархию одного действия, являющегося дочерним для запуска вызывающего метода активность. (См. рисунки)
Пример запуска активности в контроллере:
private readonly Serilog.ILogger _logger;
private readonly Service _service;

//Controller Constructor
public RateController(Serilog.ILogger seriLogger, IService service
/*, dependencies...*/
) {
//... assignment of dependencies to private fields
_logger = seriLogger.ForContext();
_service = service ? ?
throw new ArgumentNullException(nameof(service), service);
//...
}

[HttpPost]
public async Task Submit(Message request) {
using LoggerActivity activity = _logger.StartActivity("Rating {@number} from message {@MessageID}", [request.Number ? ?string.Empty, request.MessageID ? ?string.Empty]);
_service.MethodCallThatAlsoCallsStartActivity();...
}
//... Other controller actions

Пример метода, вызываемого контроллером:
private readonly Serilog.ILogger _logger;

public Service(Serilog.ILogger logger
/*dependencies... */
) {
_logger = logger.ForContext();
}

public async Task MethodCallThatAlsoCallsStartActivity() {
using LoggerActivity activity = _logger.StartActivity("New Activity");
...
}

Это фрагмент кода того, как мы регистрируем Serilog и SerilogTracing.
appsettings.json:
{ //appsettings.json
"Serilog": {
"Using": [
"Serilog.Exceptions",
"Serilog.Sinks.Console"
],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning",
"Microsoft.AspNetCore": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"formatter": "Serilog.Formatting.Compact.RenderedCompactJsonFormatter, Serilog.Formatting.Compact",
"outputTemplate": "{Timestamp:o} [{Level:u3}] {SourceContext} ({Application}/{EnvironmentName}/{EnvironmentUserName}/{RequestId}) {Message}{NewLine}{Exception}"
}
}
],
"Enrich": [
"FromLogContext",
"FromGlobalLogContext",
"WithSpan",
"WithDefaultDestructurers",
"WithEnvironmentName",
"WithEnvironmentUserName",
"WithExceptionDetails",
"WithMemoryUsage",
"WithDemystifiedStackTraces",
"WithClientIp",
"WithSpanTiming"
],
"Properties": {
"Application": "Orchestrator Service"
}
},
"AzureMonitor": {
"EnableLiveMetrics": true,
"ConnectionString": "This field was removed but contains a valid Connection String"
}
}

//Program.cs of one microservice
// reused and parameterized across other microservices in dependencies

//... bootstrap logging

WebApplicationBuilder builder = WebApplication.CreateBuilder(new WebApplicationOptions() { Args = args });

//APPLICATIONINSIGHTS_CONNECTION_STRING env var pref way to configure Application Insights

builder.Logging.ClearProviders();

builder.Services.AddSerilog((services, lc) => lc
.ReadFrom.Configuration(builder.Configuration)
.ReadFrom.Services(services), writeToProviders: true);

//... service provider registrations

builder.Logging
.AddOpenTelemetry(loggerOptions =>
{
loggerOptions.IncludeFormattedMessage = true;
loggerOptions.IncludeScopes = true;
});

builder.Services.AddOpenTelemetry()
.UseAzureMonitor();

builder.Services.Configure(options =>
{
options.Filter = (httpContext) =>
{
return !httpContext.Request.Path.Value.Contains("health") &&
!httpContext.Request.Path.Value.Contains("dapr");
};
});

using IDisposable actList = new ActivityListenerConfiguration()
.Instrument.WithDefaultInstrumentation(true)
.Instrument.HttpClientRequests()
.TraceToSharedLogger();

// ... middleware registrations in order of :
// ... exception handler, log context pushes,

app.UseRouting();
app.UseSerilogRequestLogging();
app.UseCloudEvents();
app.MapControllers();

try
{
app.Run();
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
Log.Fatal(ex, "{Application} terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
try { actList.Dispose(); } catch { /* ignored */ }
}

Это ответ от LLM, однако он ссылался на старый App Instights SDK, так что это будет моя следующая попытка.
Некоторые LLM дали такую рекомендацию.
Используйте OpenTelemetry для трассировки, Serilog для регистрации.
  • Удалите создание интервалов из Serilog
    Сохранить:

    Serilog.Enrichers.Span (for correlation IDs in logs)

    Избегайте:
    SerilogTracing.Instrumentation.AspNetCore
    TraceToSharedLogger()
    WithSpan() //for anything you expect to be a real span
  • Явное создание интервалов через ActivitySource
    Пример шаблона:
private static readonly ActivitySource ActivitySource =
new("Pricing.Orchestrator");

using var activity = ActivitySource.StartActivity(
"ResolveRatingDefinition",
ActivityKind.Internal);
  • Зарегистрируйте этот источник с помощью OpenTelemetry
services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSource("Pricing.Orchestrator")
.UseAzureMonitor();
});


Подробнее здесь: https://stackoverflow.com/questions/798 ... ched-spans
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»