function agentActivationMethodFromStartStack()

in lib/activation-method.js [40:115]


function agentActivationMethodFromStartStack(startStack, log) {
  /* @param {require('stackframe').StackFrame[]} frames */
  let frames;
  try {
    frames = errorStackParser.parse(startStack);
  } catch (parseErr) {
    log.trace(
      parseErr,
      'could not determine metadata.service.agent.activation_method',
    );
    return 'unknown';
  }
  if (frames.length < 2) {
    return 'unknown';
  }

  // frames[0].fileName = "$topDir/lib/agent.js"
  //    at Agent.start (/Users/trentm/tmp/asdf/node_modules/elastic-apm-node/lib/agent.js:241:11)
  const topDir = path.dirname(path.dirname(frames[0].fileName));

  // If this was a preload (i.e. using `-r elastic-apm-node/start`), then
  // there will be a frame with `functionName` equal to:
  // - node >=12: 'loadPreloadModules'
  // - node <12: 'preloadModules'
  const functionName = semver.gte(process.version, '12.0.0', {
    includePrerelease: true,
  })
    ? 'loadPreloadModules'
    : 'preloadModules';
  let isPreload = false;
  for (let i = frames.length - 1; i >= 2; i--) {
    if (frames[i].functionName === functionName) {
      isPreload = true;
      break;
    }
  }
  if (isPreload) {
    if (
      isLambdaExecutionEnvironment &&
      topDir === '/opt/nodejs/node_modules/elastic-apm-node'
    ) {
      // This path is defined by https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path
      // and created by "dev-utils/make-distribution.sh".
      return 'aws-lambda-layer';
    } else if (
      process.env.ELASTIC_APM_ACTIVATION_METHOD === 'K8S_ATTACH' ||
      process.env.ELASTIC_APM_ACTIVATION_METHOD === 'K8S'
    ) {
      // apm-k8s-attacher v0.1.0 started setting value to K8S.
      // v0.4.0 will start using 'K8S_ATTACH'.
      return 'k8s-attach';
    } else if (
      process.env.NODE_OPTIONS &&
      CONTAINS_R_ELASTIC_APM_NODE_START.test(process.env.NODE_OPTIONS)
    ) {
      return 'env-attach';
    } else {
      return 'preload';
    }
  }

  // To tell if elastic-apm-node was `import`d or `require`d we look for a
  // frame with `functionName` equal to 'ModuleJob.run'. This has consistently
  // been the name of this method back to at least Node v8.
  const esmImportFunctionName = 'ModuleJob.run';
  if (esmImportFunctionName) {
    for (let i = frames.length - 1; i >= 2; i--) {
      if (frames[i].functionName === esmImportFunctionName) {
        return 'import';
      }
    }
  }

  // Otherwise this was a manual `require(...)` of the agent in user code.
  return 'require';
}