deep-framework
Version:
87 lines (72 loc) • 2.91 kB
JavaScript
/**
* Express middleware module.
*
* Exposes Express middleware functions to enable automated data capturing on a web service. To enable on a Node.js/Express application,
* use 'app.use(AWSXRay.express.openSegment())' before defining your routes. After your routes, before any extra error
* handling middleware, use 'app.use(AWSXRay.express.closeSegment())'.
* Use AWSXRay.getSegment() to access the current segment/subsegment.
* Otherwise, for manual mode, this appends the Segment object to the request object as req.segment.
* @module express_mw
*/
var CLSUtils = require('../utils').CLSUtils;
var MWUtils = require('./mw_utils');
var Local = require('../segments/attributes/local');
var Segment = require('../segments/segment');
var getCauseType = require('../utils').getCauseTypeFromHttpStatus;
/**
* Use 'app.use(AWSXRay.express.openSegment('defaultName'))' before defining your routes.
* Use AWSXRay.getSegment() to access the current segment/subsegment.
* Otherwise, for manual mode, this appends the Segment object to the request object as req.segment.
* @param {string} defaultName - The default name for the segment.
* @alias module:express_mw.openSegment
* @returns {function}
*/
module.exports.openSegment = function openSegment(defaultName) {
if (!defaultName || typeof defaultName !== 'string')
throw new Error('Default segment name was not supplied. Please provide a string.');
MWUtils.setDefaultName(defaultName);
return function open(req, res, next) {
var amznTraceHeader = MWUtils.processHeaders(req);
var name = MWUtils.resolveName(req.headers.host);
var segment = new Segment(name, amznTraceHeader.Root, amznTraceHeader.Parent);
MWUtils.resolveSampling(amznTraceHeader, segment, res);
segment.addAttribute('http', new Local(req));
res.on('finish', function () {
if (this.statusCode === 429)
segment.addThrottle();
else if (getCauseType(this.statusCode))
segment[getCauseType(this.statusCode)] = true;
segment.http.close(this);
segment.close();
});
if (CLSUtils.isCLSMode()) {
var ns = CLSUtils.getNamespace();
ns.bindEmitter(req);
ns.bindEmitter(res);
ns.run(function () {
CLSUtils.setSegment(segment);
if (next) { next(); }
});
} else {
req.segment = segment;
if (next) { next(); }
}
};
};
/**
* After your routes, before any extra error handling middleware, use 'app.use(AWSXRay.express.closeSegment())'.
* @alias module:express_mw.closeSegment
* @returns {function}
*/
module.exports.closeSegment = function closeSegment() {
return function close(err, req, res, next) {
var segment = CLSUtils.isCLSMode() ? CLSUtils.getSegment() : req.segment;
if (segment && err) {
segment.close(err);
} else if (segment) {
segment.close();
}
if (next)
next(err);
};
};