deep-framework
Version:
92 lines (71 loc) • 2.85 kB
JavaScript
/**
* @module http_p
*/
var _ = require('underscore');
var CLSUtils = require('../utils').CLSUtils;
var getCauseType = require('../utils').getCauseTypeFromHttpStatus;
var logger = require('../logger');
/**
* Wraps the http/https.request() call to automatically capture information for the segment.
* @param {http|https} module - The built in Node.js HTTP or HTTPS module.
* @alias module:http_p.captureHTTPs
* @returns {http|https}
*/
var captureHTTPs = function captureHTTPs(module) {
if (module.__request)
return module;
module.__request = module.request;
module.request = function captureHTTPsRequest(options, callback) {
if (!options || (options.headers && (options.headers['X-Amzn-Trace-Id'] || options.headers['X-Amz-Date']))) {
return module.__request(options, callback);
} else if (_.isUndefined(options.Segment) && !CLSUtils.isCLSMode()) {
logger.info('Options for request ' + options + ' requires a Segment param for manual mode.');
return module.__request(options, callback);
}
var parent = options.Segment ? options.Segment : CLSUtils.getSegment();
var hostname = options.hostname || options.host || 'Unknown host';
if (_.isUndefined(parent)) {
logger.info('Options for request [ host:' + hostname + ', method:' + options.method + ', path:' +
options.path + '] requires a Segment param for manual mode.');
return module.__request(options, callback);
}
var root = parent.segment ? parent.segment : parent;
var traced = root.notTraced ? false : true;
var subsegment = parent.addNewSubsegment(hostname);
subsegment.addRemote();
var req = module.__request(_.omit(options, 'Segment'), function(res) {
res.on('end', function() {
subsegment.addRemoteData(res.req, res, traced);
subsegment.close();
});
if (typeof callback === 'function') {
if (CLSUtils.isCLSMode()) {
var session = CLSUtils.getNamespace();
session.run(function() {
CLSUtils.setSegment(subsegment);
callback(res);
});
} else {
callback(res);
}
}
});
var errorCapturer = function (e) {
if (subsegment.http) {
subsegment.close(e, getCauseType(subsegment.http.response.status), true);
} else {
subsegment.addRemoteData(req, null, traced);
subsegment.close(e);
}
if (req._events && req._events.error && req._events.error.length === 1) {
req.removeListener('error', errorCapturer);
req.emit('error', e);
}
};
req.on('error', errorCapturer);
req.setHeader('X-Amzn-Trace-Id', 'Root=' + root['trace_id'] + '; Parent=' + subsegment.id +
'; Sampled=' + (traced ? '1' : '0'));
return req;
};
};
module.exports.captureHTTPs = captureHTTPs;