Agent.prototype.start = function()

in lib/agent.js [274:383]


Agent.prototype.start = function (opts) {
  if (this.isStarted()) {
    throw new Error('Do not call .start() more than once');
  }
  global[symbols.agentInitialized] = true;

  this._config(opts);

  if (!this._conf.active) {
    this.logger.debug('Elastic APM agent disabled (`active` is false)');
    return this;
  }

  // Log preamble showing agent, environment and config relevant info
  const preambleData = this._conf.loggingPreambleData;
  const isPreviewVersion = version.indexOf('-') !== -1;
  const startStack = {};

  if (this._conf.active && this._conf.serviceName) {
    this._origStackTraceLimit = Error.stackTraceLimit;
    Error.stackTraceLimit = 20; // require more than default 10 for `agentActivationMethodFromStartStack()`
    Error.captureStackTrace(startStack);
    Error.stackTraceLimit = this._origStackTraceLimit;
    this._agentActivationMethod = agentActivationMethodFromStartStack(
      startStack,
      this.logger,
    );
    preambleData.activationMethod = this._agentActivationMethod;

    if (this._conf.logLevel === 'trace') {
      // Attempt to load package.json from process.argv.
      let pkg = null;
      try {
        var basedir = path.dirname(process.argv[1] || '.');
        pkg = require(path.join(basedir, 'package.json'));
      } catch (e) {}

      // Add stack & dependencies for extra information
      preambleData.dependencies = pkg
        ? pkg.dependencies
        : '<could not determine>';
      preambleData.startTrace = startStack.stack.split(/\n */).slice(1);
    }
  }

  this.logger.info(preambleData, 'Elastic APM Node.js Agent v%s', version);

  if (!logging.isLoggerCustom(this.logger)) {
    // Periodically dump the current config (delta from defaults) when logging
    // at "trace"-level. This allows getting the effective config from a running
    // agent by setting trace-level logging and getting 1 minute of logs.
    // (Sometimes getting logs from application *start* is no possible.)
    setInterval(() => {
      if (this.logger.isLevelEnabled('trace')) {
        try {
          const currConfig = this._conf.getCurrConfig();
          this.logger.trace({ currConfig }, 'currConfig');
        } catch (err) {
          this.logger.trace({ err }, 'error calculating currConfig');
        }
      }
    }, 60 * 1000).unref();
  }

  if (isPreviewVersion) {
    this.logger.warn(
      'Version %s is a pre-release and not intended for use in production environments',
      version,
    );
  }

  if (!this._conf.serverUrl) {
    this.logger.error(
      'Elastic APM is incorrectly configured: Invalid serverUrl (APM will be disabled)',
    );
    this._conf.active = false;
    return this;
  }

  if (!this._conf.serviceName) {
    this.logger.error(
      'Elastic APM is incorrectly configured: Missing serviceName (APM will be disabled)',
    );
    this._conf.active = false;
    return this;
  }

  initStackTraceCollection();
  this._apmClient = createApmClient(this._conf, this);

  let runContextClass;
  if (this._conf.opentelemetryBridgeEnabled) {
    const {
      setupOTelBridge,
      OTelBridgeRunContext,
    } = require('./opentelemetry-bridge');
    runContextClass = OTelBridgeRunContext;
    setupOTelBridge(this);
  }
  this._instrumentation.start(runContextClass);

  if (this._isMetricsEnabled()) {
    this._metrics.start();
  }

  Error.stackTraceLimit = this._conf.stackTraceLimit;
  if (this._conf.captureExceptions) this.handleUncaughtExceptions();

  return this;
};