Добавить трейсинг OpenTelemetry (OTLP) во все сервисы
Общая настройка DealTracingHosting (Deal.Grpc.Hosting + Deal.Api): AspNetCore/Http/GrpcNetClient инструментация, OTLP-экспорт во внешний коллектор, имя сервиса из env. Логи обогащаются TraceId/SpanId.
This commit is contained in:
@@ -18,6 +18,7 @@ WebApplication app = AiServiceHost.Create(
|
||||
{
|
||||
DealLogging.Configure(builder, aiProcessName);
|
||||
DealMetricsHosting.AddDealMetrics(builder, metricsPort);
|
||||
DealTracingHosting.AddDealTracing(builder, aiProcessName);
|
||||
});
|
||||
|
||||
DealMetricsHosting.MapDealMetrics(app);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
Версии — 1.17.x (Prometheus-экспортёр и gRPC-клиент только pre-release-линией; остальные —
|
||||
1.17.0 stable). Настройка — Deal.Api/Observability/DealMetricsHosting.cs. -->
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.17.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.17.0-beta.1" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.17.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.17.0" />
|
||||
|
||||
@@ -62,7 +62,8 @@ internal static class DealLogging
|
||||
.MinimumLevel.Is(ParseMinimumLevel(configuration[MinimumLevelEnvKey]))
|
||||
.MinimumLevel.Override(EntityFrameworkCoreCategory, LogEventLevel.Warning)
|
||||
.MinimumLevel.Override(GrpcCategory, LogEventLevel.Information)
|
||||
.Enrich.FromLogContext();
|
||||
.Enrich.FromLogContext()
|
||||
.Enrich.With<TraceContextEnricher>();
|
||||
|
||||
string logsDirectory = ResolveLogsDirectory(environment.ContentRootPath, configuration[LogsDirectoryEnvKey]);
|
||||
Directory.CreateDirectory(logsDirectory);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Diagnostics;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Deal.Api.Logging;
|
||||
|
||||
internal sealed class TraceContextEnricher : ILogEventEnricher
|
||||
{
|
||||
void ILogEventEnricher.Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||
{
|
||||
Activity? activity = Activity.Current;
|
||||
if (activity is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TraceId", activity.TraceId.ToString()));
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("SpanId", activity.SpanId.ToString()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
|
||||
namespace Deal.Api.Observability;
|
||||
|
||||
/// <summary>
|
||||
/// Настройка трейсинга ядра Deal.Api
|
||||
/// </summary>
|
||||
public static class DealTracingHosting
|
||||
{
|
||||
/// <summary>
|
||||
/// Env-ключ OTLP-endpoint коллектора
|
||||
/// </summary>
|
||||
public const string OtlpEndpointEnvKey = "OTEL_EXPORTER_OTLP_ENDPOINT";
|
||||
|
||||
/// <summary>
|
||||
/// Env-ключ имени сервиса в трейсах
|
||||
/// </summary>
|
||||
public const string ServiceNameEnvKey = "OTEL_SERVICE_NAME";
|
||||
|
||||
/// <summary>
|
||||
/// Регистрирует трейсинг OpenTelemetry с экспортом OTLP
|
||||
/// </summary>
|
||||
/// <param name="builder">Билдер ядра.</param>
|
||||
/// <param name="defaultServiceName">Имя сервиса, если env OTEL_SERVICE_NAME не задан.</param>
|
||||
public static void AddDealTracing(WebApplicationBuilder builder, string defaultServiceName)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(builder);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(defaultServiceName);
|
||||
|
||||
// Трейсинг выключен без OTLP-endpoint (dev без профиля observability): иначе экспортёр
|
||||
// вхолостую спамит ошибками соединения.
|
||||
string? endpoint = Environment.GetEnvironmentVariable(OtlpEndpointEnvKey);
|
||||
if (string.IsNullOrWhiteSpace(endpoint))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string serviceName = Environment.GetEnvironmentVariable(ServiceNameEnvKey) is { Length: > 0 } configured
|
||||
? configured
|
||||
: defaultServiceName;
|
||||
|
||||
builder.Services
|
||||
.AddOpenTelemetry()
|
||||
.WithTracing(tracing => tracing
|
||||
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(serviceName))
|
||||
.AddAspNetCoreInstrumentation()
|
||||
.AddHttpClientInstrumentation()
|
||||
.AddGrpcClientInstrumentation()
|
||||
.AddOtlpExporter(options => options.Endpoint = new Uri(endpoint)));
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ DealLogging.Configure(builder, coreProcessName);
|
||||
|
||||
int metricsPort = DealMetricsHosting.ResolveMetricsPort(DealMetricsHosting.DefaultMetricsPort);
|
||||
DealMetricsHosting.AddDealMetrics(builder, metricsPort);
|
||||
DealTracingHosting.AddDealTracing(builder, coreProcessName);
|
||||
|
||||
// Строка подключения Postgres — ТОЛЬКО из конфигурации (env/appsettings): dev-пароль в коде отсутствует
|
||||
// (Security review). Отсутствие строки = fail-fast на старте, а не тихий уход на несуществующую dev-БД.
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
ней нет; держим для будущего трейсинга). Версии — 1.17.x (Prometheus-экспортёр и gRPC-клиент
|
||||
выпускаются только pre-release-линией; остальные пакеты 1.17.0 stable). -->
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.17.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.17.0-beta.1" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.17.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.17.0" />
|
||||
|
||||
@@ -67,7 +67,8 @@ public static class DealLogging
|
||||
loggerConfiguration
|
||||
.MinimumLevel.Is(ParseMinimumLevel(configuration[MinimumLevelEnvKey]))
|
||||
.MinimumLevel.Override(GrpcCategory, LogEventLevel.Information)
|
||||
.Enrich.FromLogContext();
|
||||
.Enrich.FromLogContext()
|
||||
.Enrich.With<TraceContextEnricher>();
|
||||
|
||||
string logsDirectory = ResolveLogsDirectory(environment.ContentRootPath, configuration[LogsDirectoryEnvKey]);
|
||||
Directory.CreateDirectory(logsDirectory);
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
|
||||
namespace Deal.Grpc.Hosting.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Общая настройка трейсинга Deal-сервисов
|
||||
/// </summary>
|
||||
public static class DealTracingHosting
|
||||
{
|
||||
/// <summary>
|
||||
/// Env-ключ OTLP-endpoint коллектора
|
||||
/// </summary>
|
||||
public const string OtlpEndpointEnvKey = "OTEL_EXPORTER_OTLP_ENDPOINT";
|
||||
|
||||
/// <summary>
|
||||
/// Env-ключ имени сервиса в трейсах
|
||||
/// </summary>
|
||||
public const string ServiceNameEnvKey = "OTEL_SERVICE_NAME";
|
||||
|
||||
/// <summary>
|
||||
/// Регистрирует трейсинг OpenTelemetry с экспортом OTLP
|
||||
/// </summary>
|
||||
/// <param name="builder">Билдер хоста сервиса.</param>
|
||||
/// <param name="defaultServiceName">Имя сервиса, если env OTEL_SERVICE_NAME не задан.</param>
|
||||
public static void AddDealTracing(WebApplicationBuilder builder, string defaultServiceName)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(builder);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(defaultServiceName);
|
||||
|
||||
// Трейсинг выключен без OTLP-endpoint (dev без профиля observability): иначе экспортёр
|
||||
// вхолостую спамит ошибками соединения.
|
||||
string? endpoint = Environment.GetEnvironmentVariable(OtlpEndpointEnvKey);
|
||||
if (string.IsNullOrWhiteSpace(endpoint))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string serviceName = Environment.GetEnvironmentVariable(ServiceNameEnvKey) is { Length: > 0 } configured
|
||||
? configured
|
||||
: defaultServiceName;
|
||||
|
||||
builder.Services
|
||||
.AddOpenTelemetry()
|
||||
.WithTracing(tracing => tracing
|
||||
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(serviceName))
|
||||
.AddAspNetCoreInstrumentation()
|
||||
.AddHttpClientInstrumentation()
|
||||
.AddGrpcClientInstrumentation()
|
||||
.AddOtlpExporter(options => options.Endpoint = new Uri(endpoint)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Diagnostics;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Deal.Grpc.Hosting.Services;
|
||||
|
||||
internal sealed class TraceContextEnricher : ILogEventEnricher
|
||||
{
|
||||
void ILogEventEnricher.Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||
{
|
||||
Activity? activity = Activity.Current;
|
||||
if (activity is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TraceId", activity.TraceId.ToString()));
|
||||
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("SpanId", activity.SpanId.ToString()));
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ WebApplication app = MlServiceHost.Create(
|
||||
{
|
||||
DealLogging.Configure(builder, mlProcessName);
|
||||
DealMetricsHosting.AddDealMetrics(builder, metricsPort);
|
||||
DealTracingHosting.AddDealTracing(builder, mlProcessName);
|
||||
});
|
||||
|
||||
DealMetricsHosting.MapDealMetrics(app);
|
||||
|
||||
@@ -16,6 +16,7 @@ WebApplication app = StorageServiceHost.Create(
|
||||
{
|
||||
DealLogging.Configure(builder, storageProcessName);
|
||||
DealMetricsHosting.AddDealMetrics(builder, metricsPort);
|
||||
DealTracingHosting.AddDealTracing(builder, storageProcessName);
|
||||
});
|
||||
|
||||
DealMetricsHosting.MapDealMetrics(app);
|
||||
|
||||
@@ -18,6 +18,7 @@ WebApplication app = TelegramServiceHost.Create(
|
||||
{
|
||||
DealLogging.Configure(builder, telegramProcessName);
|
||||
DealMetricsHosting.AddDealMetrics(builder, metricsPort);
|
||||
DealTracingHosting.AddDealTracing(builder, telegramProcessName);
|
||||
});
|
||||
|
||||
DealMetricsHosting.MapDealMetrics(app);
|
||||
|
||||
Reference in New Issue
Block a user