diff --git a/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts index f44db5d9fed..04b51a9842d 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts @@ -303,28 +303,23 @@ export class AwsLambdaInstrumentation extends InstrumentationBase { span.end(); + const flushers = []; if (this._traceForceFlusher) { - this._traceForceFlusher().then( - () => callback(), - () => callback() - ); + flushers.push(this._traceForceFlusher()); } else { diag.error( 'Spans may not be exported for the lambda function because we are not force flushing before callback.' ); - callback(); } if (this._metricForceFlusher) { - this._metricForceFlusher().then( - () => callback(), - () => callback() - ); + flushers.push(this._metricForceFlusher()); } else { diag.error( 'Metrics may not be exported for the lambda function because we are not force flushing before callback.' ); - callback(); } + + Promise.all(flushers).then(callback, callback); } private _applyResponseHook( diff --git a/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts b/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts index e5978e73e35..0a067dc7586 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts @@ -181,4 +181,59 @@ describe('force flush', () => { assert.strictEqual(forceFlushed, true); }); + + it('should callback once after force flush providers', async () => { + const nodeTracerProvider = new NodeTracerProvider(); + nodeTracerProvider.addSpanProcessor( + new BatchSpanProcessor(traceMemoryExporter) + ); + nodeTracerProvider.register(); + const tracerProvider = new ProxyTracerProvider(); + tracerProvider.setDelegate(nodeTracerProvider); + let tracerForceFlushed = false; + const tracerForceFlush = () => + new Promise(resolve => { + tracerForceFlushed = true; + resolve(); + }); + nodeTracerProvider.forceFlush = tracerForceFlush; + + const meterProvider = new MeterProvider(); + meterProvider.addMetricReader( + new PeriodicExportingMetricReader({ exporter: metricMemoryExporter }) + ); + let meterForceFlushed = false; + const meterForceFlush = () => + new Promise(resolve => { + meterForceFlushed = true; + resolve(); + }); + meterProvider.forceFlush = meterForceFlush; + + process.env._HANDLER = 'lambda-test/sync.handler'; + + instrumentation = new AwsLambdaInstrumentation(); + instrumentation.setTracerProvider(tracerProvider); + instrumentation.setMeterProvider(meterProvider); + + let callbackCount = 0; + await new Promise((resolve, reject) => { + lambdaRequire('lambda-test/sync').handler( + 'arg', + ctx, + (err: Error, res: any) => { + callbackCount++; + if (err) { + reject(err); + } else { + resolve(res); + } + } + ); + }); + + assert.strictEqual(tracerForceFlushed, true); + assert.strictEqual(meterForceFlushed, true); + assert.strictEqual(callbackCount, 1); + }); });