11import { trace } from "@opentelemetry/api" ;
2- import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node" ;
32import { OTLPTraceExporter as OTLPHttpTraceExporter } from "@opentelemetry/exporter-trace-otlp-http" ;
4- import { NodeSDK } from "@opentelemetry/sdk-node" ;
3+ import { registerInstrumentations } from "@opentelemetry/instrumentation" ;
4+ import { UndiciInstrumentation } from "@opentelemetry/instrumentation-undici" ;
5+ import { resourceFromAttributes } from "@opentelemetry/resources" ;
56import {
67 BatchSpanProcessor ,
78 type ReadableSpan ,
89 type SpanProcessor ,
910} from "@opentelemetry/sdk-trace-base" ;
11+ import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node" ;
12+ import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions" ;
1013import type { MiddlewareHandler } from "hono" ;
11- import util from "util" ;
14+ import util from "node: util" ;
1215import { APIServerURLEnvironmentVariable } from "./constants" ;
1316
14- let otelSDK : NodeSDK | undefined ;
17+ let otelProvider : NodeTracerProvider | undefined ;
1518let consolePatched = false ;
1619
1720function isPlainRecord ( val : unknown ) : val is Record < string | number , unknown > {
@@ -110,14 +113,17 @@ class FilteringSpanProcessor implements SpanProcessor {
110113 }
111114}
112115
113- // Build the provider (global)
114- export function initOtel ( ) : NodeSDK {
115- if ( otelSDK ) {
116- return otelSDK ;
116+ export function initOtel ( ) : NodeTracerProvider {
117+ if ( otelProvider ) {
118+ return otelProvider ;
117119 }
118120 patchGlobalConsole ( ) ;
121+
119122 const apiUrl = process . env [ APIServerURLEnvironmentVariable ] ;
120- otelSDK = new NodeSDK ( {
123+ const provider = new NodeTracerProvider ( {
124+ resource : resourceFromAttributes ( {
125+ [ ATTR_SERVICE_NAME ] : "blink.agent" ,
126+ } ) ,
121127 spanProcessors : apiUrl
122128 ? [
123129 new FilteringSpanProcessor (
@@ -129,7 +135,7 @@ export function initOtel(): NodeSDK {
129135 } )
130136 ) ,
131137 ( span ) => {
132- // getNodeAutoInstrumentations creates an HTTP instrumentation that logs spans
138+ // UndiciInstrumentation creates an HTTP instrumentation that logs spans
133139 // for all outgoing HTTP requests, including the ones emitted by the trace exporter itself.
134140 // This creates an endless loop - we export a span, we emit a span for that export,
135141 // we export the second span, then we emit a span for that export, etc.
@@ -144,20 +150,23 @@ export function initOtel(): NodeSDK {
144150 ) ,
145151 ]
146152 : [ ] ,
153+ } ) ;
154+
155+ provider . register ( ) ;
156+
157+ registerInstrumentations ( {
147158 instrumentations : [
148- getNodeAutoInstrumentations ( {
149- "@opentelemetry/instrumentation-undici" : {
150- // our runtime wrappers make some internal requests to the agent
151- // that are detached from any other spans. we ignore such requests
152- // to avoid noise.
153- requireParentforSpans : true ,
154- } ,
159+ new UndiciInstrumentation ( {
160+ // our runtime wrappers make some internal requests to the agent
161+ // that are detached from any other spans. we ignore such requests
162+ // to avoid noise.
163+ requireParentforSpans : true ,
155164 } ) ,
156165 ] ,
157166 } ) ;
158- otelSDK . start ( ) ;
159167
160- return otelSDK ;
168+ otelProvider = provider ;
169+ return provider ;
161170}
162171
163172export const otelMiddleware : MiddlewareHandler = async ( c , next ) => {
@@ -189,14 +198,10 @@ export const otelMiddleware: MiddlewareHandler = async (c, next) => {
189198
190199export const flushOtel = async ( ) => {
191200 try {
192- if ( ! otelSDK ) {
193- return ;
194- }
195- const provider = otelSDK [ "_tracerProvider" ] ;
196- if ( ! ( provider && provider . forceFlush ) ) {
201+ if ( ! otelProvider ) {
197202 return ;
198203 }
199- await provider . forceFlush ( ) ;
204+ await otelProvider . forceFlush ( ) ;
200205 } catch ( err ) {
201206 console . warn ( "Error flushing OpenTelemetry" , err ) ;
202207 }
0 commit comments