11import { definePlugin } from "nitro" ;
2+ import type { SpanContext } from "@opentelemetry/api" ;
3+ import type {
4+ IExportTraceServiceRequest ,
5+ ISpan ,
6+ } from "@opentelemetry/otlp-transformer/build/src/trace/internal-types.js" ;
27
38/**
49 * Exports Nitro tracing-channel events to the Vercel runtime as OpenTelemetry
@@ -15,8 +20,24 @@ const SPAN_KIND_INTERNAL = 1;
1520const STATUS_CODE_ERROR = 2 ;
1621const SCOPE_NAME = "@nitro/vercel-tracing" ;
1722
18- function getTelemetry ( ) : any {
19- return ( globalThis as any ) [ REQUEST_CONTEXT_SYMBOL ] ?. get ?.( ) ?. telemetry ;
23+ /**
24+ * The Vercel runtime telemetry sink, exposed per-request via the global
25+ * `@vercel/request-context` reader. `reportSpans` is fire-and-forget; the
26+ * runtime correlates spans to the request by `rootSpanContext.traceId`.
27+ */
28+ interface VercelTelemetry {
29+ reportSpans ( data : IExportTraceServiceRequest ) : void ;
30+ rootSpanContext ?: SpanContext ;
31+ }
32+
33+ interface RequestContextReader {
34+ get ?( ) : { telemetry ?: VercelTelemetry } | undefined ;
35+ }
36+
37+ function getTelemetry ( ) : VercelTelemetry | undefined {
38+ return ( globalThis as Record < symbol , RequestContextReader | undefined > ) [
39+ REQUEST_CONTEXT_SYMBOL
40+ ] ?. get ?.( ) ?. telemetry ;
2041}
2142
2243/**
@@ -26,7 +47,7 @@ function getTelemetry(): any {
2647 * OTLP field is present even when empty (omitting e.g. `events` or `attributes`
2748 * makes the runtime drop the whole batch).
2849 */
29- class Span {
50+ class Span implements ISpan {
3051 traceId : string ;
3152 spanId : string ;
3253 // Parent on the platform root so spans appear as flat siblings.
0 commit comments