@@ -27,10 +27,13 @@ import {
2727 AwsLambdaInstrumentationConfig ,
2828} from '@opentelemetry/instrumentation-aws-lambda' ;
2929import {
30+ context ,
3031 diag ,
3132 DiagConsoleLogger ,
3233 DiagLogLevel ,
3334 metrics ,
35+ propagation ,
36+ trace ,
3437} from '@opentelemetry/api' ;
3538import { getEnv } from '@opentelemetry/core' ;
3639import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto' ;
@@ -51,8 +54,8 @@ import {
5154import { logs } from '@opentelemetry/api-logs' ;
5255
5356function defaultConfigureInstrumentations ( ) {
54- // Use require statements for instrumentation to avoid having to have transitive dependencies on all the typescript
55- // definitions.
57+ // Use require statements for instrumentation
58+ // to avoid having to have transitive dependencies on all the typescript definitions.
5659 const { DnsInstrumentation } = require ( '@opentelemetry/instrumentation-dns' ) ;
5760 const {
5861 ExpressInstrumentation,
@@ -102,7 +105,7 @@ function defaultConfigureInstrumentations() {
102105}
103106
104107declare global {
105- // in case of downstream configuring span processors etc
108+ // In case of downstream configuring span processors etc
106109 function configureAwsInstrumentation (
107110 defaultConfig : AwsSdkInstrumentationConfig ,
108111 ) : AwsSdkInstrumentationConfig ;
@@ -123,34 +126,25 @@ declare global {
123126 function configureInstrumentations ( ) : Instrumentation [ ] ;
124127}
125128
126- console . log ( 'Registering OpenTelemetry' ) ;
127-
128- const instrumentations = [
129- new AwsInstrumentation (
130- typeof configureAwsInstrumentation === 'function'
131- ? configureAwsInstrumentation ( { suppressInternalInstrumentation : true } )
132- : { suppressInternalInstrumentation : true } ,
133- ) ,
134- new AwsLambdaInstrumentation (
135- typeof configureLambdaInstrumentation === 'function'
136- ? configureLambdaInstrumentation ( { } )
137- : { } ,
138- ) ,
139- ...( typeof configureInstrumentations === 'function'
140- ? configureInstrumentations
141- : defaultConfigureInstrumentations ) ( ) ,
142- ] ;
143-
144- // configure lambda logging
145- const logLevel = getEnv ( ) . OTEL_LOG_LEVEL ;
146- diag . setLogger ( new DiagConsoleLogger ( ) , logLevel ) ;
147-
148- // Register instrumentations synchronously to ensure code is patched even before provider is ready.
149- registerInstrumentations ( {
150- instrumentations,
151- } ) ;
129+ function createInstrumentations ( ) {
130+ return [
131+ new AwsInstrumentation (
132+ typeof configureAwsInstrumentation === 'function'
133+ ? configureAwsInstrumentation ( { suppressInternalInstrumentation : true } )
134+ : { suppressInternalInstrumentation : true } ,
135+ ) ,
136+ new AwsLambdaInstrumentation (
137+ typeof configureLambdaInstrumentation === 'function'
138+ ? configureLambdaInstrumentation ( { } )
139+ : { } ,
140+ ) ,
141+ ...( typeof configureInstrumentations === 'function'
142+ ? configureInstrumentations
143+ : defaultConfigureInstrumentations ) ( ) ,
144+ ] ;
145+ }
152146
153- async function initializeProvider ( ) {
147+ function initializeProvider ( ) {
154148 const resource = detectResourcesSync ( {
155149 detectors : [ awsLambdaDetector , envDetector , processDetector ] ,
156150 } ) ;
@@ -166,12 +160,12 @@ async function initializeProvider() {
166160 if ( typeof configureTracerProvider === 'function' ) {
167161 configureTracerProvider ( tracerProvider ) ;
168162 } else {
169- // defaults
163+ // Defaults
170164 tracerProvider . addSpanProcessor (
171165 new BatchSpanProcessor ( new OTLPTraceExporter ( ) ) ,
172166 ) ;
173167 }
174- // logging for debug
168+ // Logging for debug
175169 if ( logLevel === DiagLogLevel . DEBUG ) {
176170 tracerProvider . addSpanProcessor (
177171 new SimpleSpanProcessor ( new ConsoleSpanExporter ( ) ) ,
@@ -182,7 +176,7 @@ async function initializeProvider() {
182176 if ( typeof configureSdkRegistration === 'function' ) {
183177 sdkRegistrationConfig = configureSdkRegistration ( sdkRegistrationConfig ) ;
184178 }
185- // auto -configure propagator if not provided
179+ // Auto -configure propagator if not provided
186180 if ( ! sdkRegistrationConfig . propagator ) {
187181 sdkRegistrationConfig . propagator = getPropagator ( ) ;
188182 }
@@ -223,20 +217,58 @@ async function initializeProvider() {
223217 logs . setGlobalLoggerProvider ( loggerProvider ) ;
224218 }
225219
226- // logging for debug
220+ // Logging for debug
227221 if ( logLevel === DiagLogLevel . DEBUG ) {
228222 loggerProvider . addLogRecordProcessor (
229223 new SimpleLogRecordProcessor ( new ConsoleLogRecordExporter ( ) ) ,
230224 ) ;
231225 }
232226
227+ // Create instrumentations if they have not been created before
228+ // to prevent additional coldstart overhead
229+ // caused by creations and initializations of instrumentations.
230+ if ( ! instrumentations || ! instrumentations . length ) {
231+ instrumentations = createInstrumentations ( ) ;
232+ }
233+
233234 // Re-register instrumentation with initialized provider. Patched code will see the update.
234- registerInstrumentations ( {
235+ disableInstrumentations = registerInstrumentations ( {
235236 instrumentations,
236237 tracerProvider,
237238 meterProvider,
238239 loggerProvider,
239240 } ) ;
240241}
241- // eslint-disable-next-line @typescript-eslint/no-floating-promises
242- initializeProvider ( ) ;
242+
243+ export function wrap ( ) {
244+ initializeProvider ( ) ;
245+ }
246+
247+ export function unwrap ( ) {
248+ if ( disableInstrumentations ) {
249+ disableInstrumentations ( ) ;
250+ disableInstrumentations = ( ) => { } ;
251+ }
252+ instrumentations = [ ] ;
253+ context . disable ( ) ;
254+ propagation . disable ( ) ;
255+ trace . disable ( ) ;
256+ metrics . disable ( ) ;
257+ logs . disable ( ) ;
258+ }
259+
260+ console . log ( 'Registering OpenTelemetry' ) ;
261+
262+ // Configure lambda logging
263+ const logLevel = getEnv ( ) . OTEL_LOG_LEVEL ;
264+ diag . setLogger ( new DiagConsoleLogger ( ) , logLevel ) ;
265+
266+ let instrumentations = createInstrumentations ( ) ;
267+ let disableInstrumentations : ( ) => void ;
268+
269+ // Register instrumentations synchronously to ensure code is patched even before provider is ready.
270+ disableInstrumentations = registerInstrumentations ( {
271+ instrumentations,
272+ } ) ;
273+
274+ wrap ( ) ;
0 commit comments