# OTel Integration — Budget Wire up OpenTelemetry in Budget.Api so logs and traces flow through the OTel Collector to Seq. Depends on the infrastructure plan (`docker/.plans/otel-seq-infrastructure.md`) being applied first. ## Packages to add (Budget.Api.csproj) Verify latest stable versions on NuGet before adding — do not guess. ``` OpenTelemetry.Extensions.Hosting OpenTelemetry.Instrumentation.AspNetCore OpenTelemetry.Instrumentation.Http OpenTelemetry.Instrumentation.EntityFrameworkCore OpenTelemetry.Exporter.OpenTelemetryProtocol ``` ## Phase 1 — Wire up OTel in Program.cs Add after `var builder = WebApplication.CreateBuilder(args);`: ```csharp builder.Logging.AddOpenTelemetry(logging => { logging.IncludeFormattedMessage = true; logging.IncludeScopes = true; }); builder.Services.AddOpenTelemetry() .ConfigureResource(resource => resource .AddService(serviceName: "budget", serviceVersion: "1.0.0")) .WithLogging() .WithTracing(tracing => tracing .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddEntityFrameworkCoreInstrumentation() .AddOtlpExporter()); ``` The `AddOtlpExporter()` call with no arguments reads the endpoint from environment variables (`OTEL_EXPORTER_OTLP_ENDPOINT`), keeping config out of code. ## Phase 2 — docker-compose environment variables Add to the `budget` service in `docker/docker-compose.yaml`: ```yaml - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 - OTEL_EXPORTER_OTLP_PROTOCOL=grpc - OTEL_SERVICE_NAME=budget ``` `otel-collector` resolves via the `telemetry` network added in the infrastructure plan. ## Phase 3 — Verification 1. Build and push a new Budget image 2. `docker compose up -d budget` 3. Make a few API calls (create a transaction, fetch accounts) 4. In Seq, search `@ServiceName = 'budget'` — you should see structured log events including the OIDC discovery retry loop logs already present in Program.cs 5. Confirm DB spans appear for EF Core queries ## Notes - Budget already has structured logging calls in the OIDC startup retry loop (`startupLogger.LogInformation`, `LogWarning`). These will automatically become structured events in Seq with no code changes. - The `ErrorHandlingMiddleware` and `KnownUserMiddleware` are good candidates to add structured properties (e.g. `userId`, `endpoint`) to log calls, making Seq searches more useful. - `AddHttpClientInstrumentation()` will trace outgoing calls to the Auth server (OIDC discovery, token introspection), which is useful for diagnosing auth latency.