66'use strict' ;
77
88const instanaCore = require ( '@instana/core' ) ;
9- const { backendConnector, consoleLogger : log , environment } = require ( '@instana/serverless' ) ;
9+ const { backendConnector, consoleLogger : serverlessLogger , environment } = require ( '@instana/serverless' ) ;
1010const arnParser = require ( './arn' ) ;
1111const identityProvider = require ( './identity_provider' ) ;
1212const metrics = require ( './metrics' ) ;
@@ -15,21 +15,29 @@ const triggers = require('./triggers');
1515const processResult = require ( './process_result' ) ;
1616const captureHeaders = require ( './capture_headers' ) ;
1717
18- const { tracing, util : coreUtil } = instanaCore ;
19- const { normalizeConfig } = coreUtil ;
18+ const { tracing, coreConfig, coreUtils } = instanaCore ;
2019const { tracingHeaders, constants, spanBuffer } = tracing ;
2120
2221const lambdaConfigDefaults = {
2322 tracing : { forceTransmissionStartingAt : 25 , transmissionDelay : 100 , initialTransmissionDelay : 100 }
2423} ;
2524
26- const logger = log . init ( ) ;
27- let config = normalizeConfig ( { } , logger , lambdaConfigDefaults ) ;
2825let coldStart = true ;
2926
27+ const instanaCtr = new instanaCore . InstanaCtr ( ) ;
28+
29+ coreUtils . init ( instanaCtr ) ;
30+ coreConfig . init ( instanaCtr ) ;
31+ serverlessLogger . init ( instanaCtr ) ;
32+
33+ instanaCtr . set ( 'utils' , coreUtils . create ( ) ) ;
34+ instanaCtr . set ( 'config' , coreConfig . create ( { } , lambdaConfigDefaults ) ) ;
35+ instanaCtr . set ( 'logger' , serverlessLogger . create ( ) ) ;
36+
3037// Initialize instrumentations early to allow for require statements after our
3138// package has been required but before the actual instana.wrap(...) call.
32- instanaCore . preInit ( config ) ;
39+ // TODO: refactor to use `instanaCtr` only!
40+ instanaCore . preInit ( instanaCtr . config ( ) , instanaCtr . utils ( ) ) ;
3341
3442/**
3543 * Wraps an AWS Lambda handler so that metrics and traces are reported to Instana. This function will figure out if the
@@ -191,7 +199,7 @@ function shimmedHandler(originalHandler, originalThis, originalArgs, _config) {
191199 process . env . INSTANA_ENABLE_LAMBDA_TIMEOUT_DETECTION &&
192200 process . env . INSTANA_ENABLE_LAMBDA_TIMEOUT_DETECTION === 'true'
193201 ) {
194- logger . debug ( 'Heuristical timeout detection enabled. Please only use for debugging purposes.' ) ;
202+ instanaCtr . logger ( ) . debug ( 'Heuristical timeout detection enabled. Please only use for debugging purposes.' ) ;
195203 registerTimeoutDetection ( context , entrySpan ) ;
196204 }
197205
@@ -245,34 +253,41 @@ function init(event, arnInfo, _config) {
245253
246254 // CASE: customer provides a custom logger or custom level
247255 if ( customConfig . logger || customConfig . level ) {
248- log . init ( customConfig ) ;
256+ instanaCtr . setLogger ( serverlessLogger . create ( customConfig ) ) ;
249257 }
250258
251- // NOTE: We SHOULD renormalize because of :
259+ // NOTE: We SHOULD re-create the config object, because :
252260 // - in-code _config object
253261 // - late env variables (less likely)
254262 // - custom logger
255263 // - we always renormalize unconditionally to ensure safety.
256- config = normalizeConfig ( customConfig , logger , lambdaConfigDefaults ) ;
264+ // This is a consequence of pre-initializing early.
265+ instanaCtr . set ( 'config' , coreConfig . create ( customConfig , lambdaConfigDefaults ) ) ;
257266
258- if ( ! config . tracing . enabled ) {
267+ if ( ! instanaCtr . config ( ) . tracing . enabled ) {
259268 return false ;
260269 }
261270
262271 const useLambdaExtension = shouldUseLambdaExtension ( ) ;
263272 if ( useLambdaExtension ) {
264- logger . info ( '@instana/aws-lambda will use the Instana Lambda extension to send data to the Instana back end.' ) ;
273+ instanaCtr
274+ . logger ( )
275+ . info ( '@instana/aws-lambda will use the Instana Lambda extension to send data to the Instana back end.' ) ;
265276 } else {
266- logger . info (
267- '@instana/aws-lambda will not use the Instana Lambda extension, but instead send data to the Instana back end ' +
268- 'directly.'
269- ) ;
277+ instanaCtr
278+ . logger ( )
279+ . info (
280+ '@instana/aws-lambda will not use the Instana Lambda extension, ' +
281+ 'but instead send data to the Instana back end ' +
282+ 'directly.'
283+ ) ;
270284 }
271285
272286 identityProvider . init ( arnInfo ) ;
273- triggers . init ( config ) ;
287+ triggers . init ( instanaCtr . config ( ) ) ;
288+
274289 backendConnector . init ( {
275- config,
290+ config : instanaCtr . config ( ) ,
276291 identityProvider,
277292 defaultTimeout : 500 ,
278293 useLambdaExtension,
@@ -282,16 +297,16 @@ function init(event, arnInfo, _config) {
282297 retries : ! ! useLambdaExtension
283298 } ) ;
284299
285- instanaCore . init ( config , backendConnector , identityProvider ) ;
300+ instanaCore . init ( instanaCtr . config ( ) , instanaCtr . utils ( ) , backendConnector , identityProvider ) ;
286301
287302 // After core init, because ssm requires require('@aws-sdk/client-ssm'), which triggers
288303 // the requireHook + shimmer. Any module which requires another external module has to be
289304 // initialized after the core.
290- ssm . init ( config ) ;
305+ ssm . init ( instanaCtr . config ( ) ) ;
291306
292307 spanBuffer . setIsFaaS ( true ) ;
293- captureHeaders . init ( config ) ;
294- metrics . init ( config ) ;
308+ captureHeaders . init ( instanaCtr . config ( ) ) ;
309+ metrics . init ( instanaCtr . config ( ) ) ;
295310 metrics . activate ( ) ;
296311 tracing . activate ( ) ;
297312
@@ -311,10 +326,12 @@ function registerTimeoutDetection(context, entrySpan) {
311326 : 2000 ;
312327
313328 if ( initialRemainingMillis <= minimumTimeoutInMs ) {
314- logger . debug (
315- 'Heuristical timeout detection will be disabled for Lambda functions with a short timeout ' +
316- '(2 seconds and smaller).'
317- ) ;
329+ instanaCtr
330+ . logger ( )
331+ . debug (
332+ 'Heuristical timeout detection will be disabled for Lambda functions with a short timeout ' +
333+ '(2 seconds and smaller).'
334+ ) ;
318335 return ;
319336 }
320337
@@ -329,9 +346,9 @@ function registerTimeoutDetection(context, entrySpan) {
329346 triggerTimeoutHandlingAfter = initialRemainingMillis - 400 ;
330347 }
331348
332- logger . debug (
333- `Registering heuristical timeout detection to be triggered in ${ triggerTimeoutHandlingAfter } milliseconds.`
334- ) ;
349+ instanaCtr
350+ . logger ( )
351+ . debug ( `Registering heuristical timeout detection to be triggered in ${ triggerTimeoutHandlingAfter } milliseconds.` ) ;
335352
336353 setTimeout ( ( ) => {
337354 postHandlerForTimeout ( entrySpan , getRemainingTimeInMillis ( context ) ) ;
@@ -342,7 +359,9 @@ function getRemainingTimeInMillis(context) {
342359 if ( context && typeof context . getRemainingTimeInMillis === 'function' ) {
343360 return context . getRemainingTimeInMillis ( ) ;
344361 } else {
345- logger . warn ( 'context.getRemainingTimeInMillis() is not available, timeout detection will be disabled.' ) ;
362+ instanaCtr
363+ . logger ( )
364+ . warn ( 'context.getRemainingTimeInMillis() is not available, timeout detection will be disabled.' ) ;
346365 return null ;
347366 }
348367}
@@ -352,36 +371,41 @@ function getRemainingTimeInMillis(context) {
352371// used or not e.g. by checking the lambda handler name if that is possible.
353372function shouldUseLambdaExtension ( ) {
354373 if ( process . env . INSTANA_DISABLE_LAMBDA_EXTENSION ) {
355- logger . info ( 'INSTANA_DISABLE_LAMBDA_EXTENSION is set, not using the Lambda extension.' ) ;
374+ instanaCtr . logger ( ) . info ( 'INSTANA_DISABLE_LAMBDA_EXTENSION is set, not using the Lambda extension.' ) ;
356375 return false ;
357376 } else {
358377 // Note: We could also use context.memoryLimitInMB here instead of the env var AWS_LAMBDA_FUNCTION_MEMORY_SIZE (both
359378 // should always yield the same value), but this behaviour needs to be in sync with what the Lambda extension does.
360379 // The context object is not available to the extension, so we prefer the env var over the value from the context.
361380 const memorySetting = process . env . AWS_LAMBDA_FUNCTION_MEMORY_SIZE ;
362381 if ( ! memorySetting ) {
363- logger . debug (
364- 'The environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE is not present, cannot determine memory settings.'
365- ) ;
382+ instanaCtr
383+ . logger ( )
384+ . debug (
385+ 'The environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE is not present, cannot determine memory settings.'
386+ ) ;
366387 return true ;
367388 }
368389 const memorySize = parseInt ( memorySetting , 10 ) ;
369390 if ( isNaN ( memorySize ) ) {
370- logger . debug (
371- `Could not parse the value of the environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE: "${ memorySetting } ", ` +
372- 'cannot determine memory settings, not using the Lambda extension.'
373- ) ;
391+ instanaCtr
392+ . logger ( )
393+ . debug (
394+ 'Could not parse the value of the environment variable ' +
395+ `AWS_LAMBDA_FUNCTION_MEMORY_SIZE: "${ memorySetting } ", ` +
396+ 'cannot determine memory settings, not using the Lambda extension.'
397+ ) ;
374398 return false ;
375399 }
376400 if ( memorySize < 256 ) {
377- let logFn = logger . debug ;
401+ let logFn = instanaCtr . logger ( ) . debug ;
378402
379403 // CASE: We try to determine if the customer has the extension installed. We need to put a warning
380404 // because the extension is **not** working and might block the lambda extension when
381405 // its not used correctly e.g. slow startup of extension or waiting for invokes or incoming spans
382406 // from the tracer.
383407 if ( process . env . _HANDLER ?. includes ( 'instana-aws-lambda-auto-wrap' ) ) {
384- logFn = logger . warn ;
408+ logFn = instanaCtr . logger ( ) . warn ;
385409 }
386410
387411 logFn (
@@ -428,7 +452,7 @@ function sendToBackend({ spans, metricsPayload, finalLambdaRequest, callback })
428452
429453 return ssm . waitAndGetInstanaKey ( ( err , value ) => {
430454 if ( err ) {
431- logger . debug ( err ) ;
455+ instanaCtr . logger ( ) . debug ( err ) ;
432456 return callback ( ) ;
433457 }
434458
@@ -513,14 +537,14 @@ function postHandlerForTimeout(entrySpan, remainingMillis) {
513537 * `setTimeout` is not 100% reliable
514538 */
515539 if ( remainingMillis < 200 ) {
516- logger . debug ( 'Skipping heuristical timeout detection because lambda timeout exceeded already.' ) ;
540+ instanaCtr . logger ( ) . debug ( 'Skipping heuristical timeout detection because lambda timeout exceeded already.' ) ;
517541 return ;
518542 }
519543
520544 if ( entrySpan ) {
521545 // CASE: Timeout not needed, we already send the data to the backend successfully
522546 if ( entrySpan . transmitted ) {
523- logger . debug ( 'Skipping heuristical timeout detection because BE data was sent already.' ) ;
547+ instanaCtr . logger ( ) . debug ( 'Skipping heuristical timeout detection because BE data was sent already.' ) ;
524548 return ;
525549 }
526550
@@ -531,7 +555,7 @@ function postHandlerForTimeout(entrySpan, remainingMillis) {
531555 entrySpan . transmit ( ) ;
532556 }
533557
534- logger . debug ( `Heuristical timeout detection was triggered with ${ remainingMillis } milliseconds left.` ) ;
558+ instanaCtr . logger ( ) . debug ( `Heuristical timeout detection was triggered with ${ remainingMillis } milliseconds left.` ) ;
535559
536560 // deliberately not gathering metrics but only sending spans.
537561 const spans = spanBuffer . getAndResetSpans ( ) ;
@@ -551,7 +575,7 @@ exports.currentSpan = function getHandleForCurrentSpan() {
551575exports . sdk = tracing . sdk ;
552576
553577exports . setLogger = function setLogger ( _logger ) {
554- log . init ( { logger : _logger } ) ;
578+ instanaCtr . logger ( ) . setLogger ( _logger ) ;
555579} ;
556580
557581exports . opentracing = tracing . opentracing ;
0 commit comments