From ca5a873bee1778d19c3acb98c74b7d9e84d2c31d Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 29 Nov 2023 16:23:45 +0700 Subject: [PATCH] enrich all traces with user id --- backend/LexBoxApi/Otel/OtelKernel.cs | 13 ++++++++++++- frontend/src/lib/otel/otel.client.ts | 10 +++++++++- frontend/src/lib/otel/otel.shared.ts | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/backend/LexBoxApi/Otel/OtelKernel.cs b/backend/LexBoxApi/Otel/OtelKernel.cs index 937389ff7..16872c494 100644 --- a/backend/LexBoxApi/Otel/OtelKernel.cs +++ b/backend/LexBoxApi/Otel/OtelKernel.cs @@ -4,6 +4,7 @@ using LexBoxApi.Services; using LexCore.Auth; using Npgsql; +using OpenTelemetry; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; @@ -28,6 +29,7 @@ public static void AddOpenTelemetryInstrumentation(this IServiceCollection servi configuration.Bind("Otel", options); }) .AddSource(ServiceName) + .AddProcessor() .SetResourceBuilder(appResourceBuilder) // could potentially add baggage to the trace as done in // https://github.com/honeycombio/honeycomb-opentelemetry-dotnet/blob/main/src/Honeycomb.OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs @@ -109,6 +111,15 @@ private static void EnrichWithUser(this Activity activity, HttpContext httpConte { activity.SetTag("app.user.role", userRole); } - activity.SetTag("http.abort", httpContext.RequestAborted.IsCancellationRequested); + if (httpContext.RequestAborted.IsCancellationRequested) + activity.SetTag("http.abort", true); + } + + private class UserEnricher(IHttpContextAccessor contextAccessor) : BaseProcessor + { + public override void OnStart(Activity data) + { + if (contextAccessor.HttpContext is {} context) data.EnrichWithUser(context); + } } } diff --git a/frontend/src/lib/otel/otel.client.ts b/frontend/src/lib/otel/otel.client.ts index 90b8e8eda..bc0805d92 100644 --- a/frontend/src/lib/otel/otel.client.ts +++ b/frontend/src/lib/otel/otel.client.ts @@ -3,7 +3,7 @@ import { BatchSpanProcessor, WebTracerProvider } from '@opentelemetry/sdk-trace- import { APP_VERSION } from '$lib/util/version'; import { OTLPTraceExporterBrowserWithXhrRetry } from './trace-exporter-browser-with-xhr-retry'; import { Resource } from '@opentelemetry/resources' -import { SERVICE_NAME } from '.' +import {SERVICE_NAME, traceUserAttributes} from '.'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions' import { ZoneContextManager } from '@opentelemetry/context-zone' import { getWebAutoInstrumentations } from '@opentelemetry/auto-instrumentations-web' @@ -27,6 +27,14 @@ const resource = Resource.default().merge( const provider = new WebTracerProvider({ resource: resource, }); +provider.addSpanProcessor({ +forceFlush: () => Promise.resolve(), + onStart: (span) => { + traceUserAttributes(span); + }, + onEnd: () => {}, + shutdown: () => Promise.resolve(), +}); const exporter = new OTLPTraceExporterBrowserWithXhrRetry({ url: '/v1/traces' }); diff --git a/frontend/src/lib/otel/otel.shared.ts b/frontend/src/lib/otel/otel.shared.ts index 48a4c331e..f492d6e2a 100644 --- a/frontend/src/lib/otel/otel.shared.ts +++ b/frontend/src/lib/otel/otel.shared.ts @@ -150,7 +150,7 @@ function getUser(event?: RequestEvent | NavigationEvent | Event): LexAuthUser | } } } -function traceUserAttributes(span: Span, event?: RequestEvent | NavigationEvent | Event): void { +export function traceUserAttributes(span: Span, event?: RequestEvent | NavigationEvent | Event): void { const user = getUser(event); if (user) { span.setAttribute('app.user.id', user.id);