| | | 1 | | import { |
| | | 2 | | context, |
| | | 3 | | propagation, |
| | | 4 | | SpanStatusCode, |
| | | 5 | | trace, |
| | | 6 | | } from "@opentelemetry/api"; |
| | | 7 | | |
| | | 8 | | import { headersTextMapGetter } from "./propagation"; |
| | | 9 | | |
| | 0 | 10 | | export function withSsrRequestSpan<T>( |
| | | 11 | | request: Request, |
| | | 12 | | fn: () => Promise<T>, |
| | | 13 | | ): Promise<T> { |
| | 0 | 14 | | const parentCtx = propagation.extract( |
| | | 15 | | context.active(), |
| | | 16 | | request.headers, |
| | | 17 | | headersTextMapGetter, |
| | | 18 | | ); |
| | | 19 | | |
| | 0 | 20 | | return context.with(parentCtx, async () => { |
| | 0 | 21 | | const tracer = trace.getTracer("clutterstock.react-router"); |
| | 0 | 22 | | const span = tracer.startSpan("ssr.document", { |
| | | 23 | | attributes: { |
| | | 24 | | "http.request.method": request.method, |
| | | 25 | | "url.full": request.url, |
| | | 26 | | }, |
| | | 27 | | }); |
| | 0 | 28 | | const spanCtx = trace.setSpan(context.active(), span); |
| | | 29 | | |
| | 0 | 30 | | try { |
| | 0 | 31 | | const result = await context.with(spanCtx, fn); |
| | 0 | 32 | | span.setStatus({ code: SpanStatusCode.OK }); |
| | 0 | 33 | | return result; |
| | | 34 | | } catch (err) { |
| | 0 | 35 | | span.recordException(err as Error); |
| | 0 | 36 | | span.setStatus({ |
| | | 37 | | code: SpanStatusCode.ERROR, |
| | | 38 | | message: err instanceof Error ? err.message : String(err), |
| | | 39 | | }); |
| | 0 | 40 | | throw err; |
| | | 41 | | } finally { |
| | 0 | 42 | | span.end(); |
| | | 43 | | } |
| | | 44 | | }); |
| | | 45 | | } |