Files
baya-monorepo/server/src/Infrastructure/Baya.Infrastructure.Monitoring/Configurations/OpenTelemetryConfigurations.cs
T
2026-07-13 22:52:57 +03:30

64 lines
2.9 KiB
C#

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace Baya.Infrastructure.Monitoring.Configurations;
/// <summary>
/// The single OpenTelemetry stack (refinement-phase-9, §9.1). Metrics and traces share one resource
/// (<c>service.name = Baya.Web.Api</c>). Metrics are scraped by Prometheus (the <c>/metrics</c> endpoint,
/// wired in <see cref="PrometheusMetricsConfigurations"/>); traces cover ASP.NET Core requests and EF Core
/// commands so a cross-service money flow (webhook → confirm → ledger) can be followed end to end. The
/// request's trace id is the <c>ApiResult.RequestId</c> the client sees, so a support ticket maps 1:1 to a
/// trace.
/// <para>The prior duplicate prometheus-net stack was removed — OpenTelemetry is now the only metrics source.</para>
/// <para>OTLP export (traces + metrics) is <b>opt-in</b>: it is wired only when <c>OpenTelemetry:Otlp:Endpoint</c>
/// is configured, so an MVP deployment with Prometheus alone runs unchanged and no exporter spams connection
/// errors against an absent collector.</para>
/// </summary>
public static class OpenTelemetryConfigurations
{
public const string ServiceName = "Baya.Web.Api";
public static WebApplicationBuilder SetupOpenTelemetry(this WebApplicationBuilder builder)
{
var otlpEndpoint = builder.Configuration["OpenTelemetry:Otlp:Endpoint"];
var hasOtlp = !string.IsNullOrWhiteSpace(otlpEndpoint);
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService(ServiceName))
.WithMetrics(metricsBuilder =>
{
metricsBuilder.AddRuntimeInstrumentation()
.AddAspNetCoreInstrumentation()
.AddMeter("Microsoft.AspNetCore.Hosting"
, "Microsoft.AspNetCore.Server.Kestrel"
, "System.Net.Http"
, "Baya.Web.Api"
, "ControllerMetrics"
// The mediator request-duration histogram (MetricsBehaviour) — captured here so the one
// metrics stack actually exports it (the removed prometheus-net stack never did).
, "mediator_meter")
.AddPrometheusExporter();
if (hasOtlp)
metricsBuilder.AddOtlpExporter(options => options.Endpoint = new Uri(otlpEndpoint!));
})
.WithTracing(tracingBuilder =>
{
tracingBuilder.AddAspNetCoreInstrumentation()
.AddEntityFrameworkCoreInstrumentation();
if (hasOtlp)
tracingBuilder.AddOtlpExporter(options => options.Endpoint = new Uri(otlpEndpoint!));
});
builder.Services.AddMetrics();
return builder;
}
}