function captureAWSRequest()

in packages/core/lib/patchers/aws_p.js [60:169]


function captureAWSRequest(req) {
  var parent = contextUtils.resolveSegment(contextUtils.resolveManualSegmentParams(req.params));

  if (!parent) {
    var output = this.serviceIdentifier + '.' + req.operation;

    if (!contextUtils.isAutomaticMode()) {
      logger.getLogger().info('Call ' + output + ' requires a segment object' +
        ' on the request params as "XRaySegment" for tracing in manual mode. Ignoring.');
    } else {
      logger.getLogger().info('Call ' + output +
        ' is missing the sub/segment context for automatic mode. Ignoring.');
    }
    return req;
  }

  var throttledError = this.throttledError || throttledErrorDefault;

  var stack = (new Error()).stack;

  let subsegment;
  if (parent.notTraced) {
    subsegment = parent.addNewSubsegmentWithoutSampling(this.serviceIdentifier);
  } else {
    subsegment = parent.addNewSubsegment(this.serviceIdentifier);
  }

  var traceId = parent.segment ? parent.segment.trace_id : parent.trace_id;
  const data = parent.segment ? parent.segment.additionalTraceData : parent.additionalTraceData;

  var buildListener = function(req) {
    if (parent.noOp) {
      return;
    }
    let traceHeader = 'Root=' + traceId + ';Parent=' + subsegment.id +
      ';Sampled=' + (subsegment.notTraced ? '0' : '1');
    if (data != null) {
      for (const [key, value] of Object.entries(data)) {
        traceHeader += ';' + key +'=' + value;
      }
    }
    req.httpRequest.headers['X-Amzn-Trace-Id'] = traceHeader;
  };

  var completeListener = function(res) {
    subsegment.addAttribute('namespace', 'aws');
    subsegment.addAttribute('aws', new Aws(res, subsegment.name));

    var httpRes = res.httpResponse;

    if (httpRes) {
      subsegment.addAttribute('http', new HttpResponse(httpRes));

      if (httpRes.statusCode === 429 || (res.error && throttledError(res.error))) {
        subsegment.addThrottleFlag();
      }
    }

    if (res.error) {
      var err = { message: res.error.message, name: res.error.code, stack: stack };

      if (httpRes && httpRes.statusCode) {
        if (Utils.getCauseTypeFromHttpStatus(httpRes.statusCode) == 'error') {
          subsegment.addErrorFlag();
        }
        subsegment.close(err, true);
      } else {
        subsegment.close(err);
      }
    } else {
      if (httpRes && httpRes.statusCode) {
        var cause = Utils.getCauseTypeFromHttpStatus(httpRes.statusCode);

        if (cause) {
          subsegment[cause] = true;
        }
      }
      subsegment.close();
    }
  };

  req.on('beforePresign', function(req) {
    // Only the AWS Presigner triggers this event,
    // so we can rely on this event to notify us when
    // a request is for a presigned url
    parent.removeSubsegment(subsegment);
    parent.decrementCounter();
    req.removeListener('build', buildListener);
    req.removeListener('complete', completeListener);
  });

  req.on('build', buildListener).on('complete', completeListener);

  if (!req.__send) {
    req.__send = req.send;

    req.send = function(callback) {
      if (contextUtils.isAutomaticMode()) {
        var session = contextUtils.getNamespace();

        session.run(function() {
          contextUtils.setSegment(subsegment);
          req.__send(callback);
        });
      } else {
        req.__send(callback);
      }
    };
  }
}