1- import { NodeSDK } from "@opentelemetry/sdk-node" ;
1+ import { NodeSDK , logs } from "@opentelemetry/sdk-node" ;
22import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node" ;
33import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto" ;
44import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto" ;
@@ -7,6 +7,8 @@ import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
77import { resourceFromAttributes } from "@opentelemetry/resources" ;
88import { ATTR_SERVICE_NAME , ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions" ;
99
10+ const { BatchLogRecordProcessor } = logs ;
11+
1012// Only initialize OpenTelemetry in production (unless OTEL_ENABLED is explicitly set to "true")
1113const isProduction = process . env . NODE_ENV === "production" ;
1214const otelExplicitlyEnabled = process . env . OTEL_ENABLED === "true" ;
@@ -50,54 +52,54 @@ if (shouldEnableOtel) {
5052 } ) ;
5153
5254 // Initialize OpenTelemetry SDK
53- const sdk = new NodeSDK ( {
54- resource,
55- traceExporter,
56- metricReader : new PeriodicExportingMetricReader ( {
57- exporter : metricExporter ,
58- exportIntervalMillis : 60000 , // Export metrics every 60 seconds
59- } ) ,
60- logRecordProcessor : logExporter as any , // Type compatibility
61- instrumentations : [
62- getNodeAutoInstrumentations ( {
63- // Automatic instrumentation for HTTP, gRPC, database clients, etc.
64- "@opentelemetry/instrumentation-http" : {
65- enabled : true ,
66- } ,
67- "@opentelemetry/instrumentation-express" : {
68- enabled : false , // We're using Hono, not Express
69- } ,
70- "@opentelemetry/instrumentation-pg" : {
71- enabled : true , // PostgreSQL instrumentation
72- } ,
73- "@opentelemetry/instrumentation-redis" : {
74- enabled : true , // Redis instrumentation for Upstash
75- } ,
55+ try {
56+ const sdk = new NodeSDK ( {
57+ resource,
58+ traceExporter,
59+ metricReader : new PeriodicExportingMetricReader ( {
60+ exporter : metricExporter ,
61+ exportIntervalMillis : 60000 , // Export metrics every 60 seconds
7662 } ) ,
77- ] ,
78- } ) ;
79-
80- // Start the SDK
81- sdk
82- . start ( )
83- . then ( ( ) => {
84- console . log ( "✅ OpenTelemetry initialized with Grafana Cloud" ) ;
85- console . log ( `📊 Service: ${ serviceName } (v${ serviceVersion } )` ) ;
86- console . log ( `🌍 Environment: ${ environment } ` ) ;
87- console . log ( `🔗 Endpoint: ${ process . env . OTEL_EXPORTER_OTLP_ENDPOINT } ` ) ;
88- } )
89- . catch ( ( error ) => {
90- console . error ( "❌ Error initializing OpenTelemetry:" , error ) ;
63+ logRecordProcessor : new BatchLogRecordProcessor ( logExporter ) ,
64+ instrumentations : [
65+ getNodeAutoInstrumentations ( {
66+ // Automatic instrumentation for HTTP, gRPC, database clients, etc.
67+ "@opentelemetry/instrumentation-http" : {
68+ enabled : true ,
69+ } ,
70+ "@opentelemetry/instrumentation-express" : {
71+ enabled : false , // We're using Hono, not Express
72+ } ,
73+ "@opentelemetry/instrumentation-pg" : {
74+ enabled : true , // PostgreSQL instrumentation
75+ } ,
76+ "@opentelemetry/instrumentation-redis" : {
77+ enabled : true , // Redis instrumentation for Upstash
78+ } ,
79+ } ) ,
80+ ] ,
9181 } ) ;
9282
93- // Graceful shutdown
94- process . on ( "SIGTERM" , ( ) => {
95- sdk
96- . shutdown ( )
97- . then ( ( ) => console . log ( "OpenTelemetry SDK shut down successfully" ) )
98- . catch ( ( error ) => console . error ( "Error shutting down OpenTelemetry SDK:" , error ) )
99- . finally ( ( ) => process . exit ( 0 ) ) ;
100- } ) ;
83+ // Start the SDK (synchronous operation)
84+ sdk . start ( ) ;
85+
86+ console . log ( "✅ OpenTelemetry initialized with Grafana Cloud" ) ;
87+ console . log ( `📊 Service: ${ serviceName } (v${ serviceVersion } )` ) ;
88+ console . log ( `🌍 Environment: ${ environment } ` ) ;
89+ console . log ( `🔗 Endpoint: ${ process . env . OTEL_EXPORTER_OTLP_ENDPOINT } ` ) ;
90+
91+ // Graceful shutdown
92+ process . on ( "SIGTERM" , ( ) => {
93+ sdk
94+ . shutdown ( )
95+ . then ( ( ) => console . log ( "OpenTelemetry SDK shut down successfully" ) )
96+ . catch ( ( error ) => console . error ( "Error shutting down OpenTelemetry SDK:" , error ) )
97+ . finally ( ( ) => process . exit ( 0 ) ) ;
98+ } ) ;
99+ } catch ( error ) {
100+ console . error ( "❌ Error initializing OpenTelemetry SDK:" , error ) ;
101+ console . error ( " OpenTelemetry will be disabled. Application will continue without observability." ) ;
102+ }
101103} else {
102104 const reason = ! process . env . OTEL_EXPORTER_OTLP_ENDPOINT
103105 ? "OTEL_EXPORTER_OTLP_ENDPOINT not set"
0 commit comments