sdk_contrib/koa/lib/koa_mw.js (73 lines of code) (raw):

/** * Koa middleware module. * * Exposes Koa middleware functions to enable automated data capturing on a web service. * To enable on a Node.js/Koa application, use 'app.use(AWSXRayKoa.openSegment(<name>))' before defining your routes. * Use AWSXRay.getSegment() to access the current sub/segment. * Otherwise, for manual mode this appends the Segment object to the context object as ctx.segment. * @module koa_mw */ const AWSXRay = require('aws-xray-sdk-core'); const mwUtils = AWSXRay.middleware; const IncomingRequestData = mwUtils.IncomingRequestData; const Segment = AWSXRay.Segment; const koaMW = { /** * Use 'app.use(AWSXRayKoa.openSegment(<name>))' before defining your routes. * Use AWSXRay.getSegment() to access the current sub/segment. * Otherwise, for manual mode, this appends the Segment object to the request object as ctx.segment. * @param {string} defaultName - The default name for the segment. * @alias module:koa_mw.openSegment * @returns {function} */ 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 async (ctx, next) => { const amznTraceHeader = mwUtils.processHeaders(ctx); const name = mwUtils.resolveName(ctx.host); const segment = new Segment( name, amznTraceHeader.Root || amznTraceHeader.root, amznTraceHeader.Parent || amznTraceHeader.parent ); mwUtils.resolveSampling(amznTraceHeader, segment, ctx); segment.addIncomingRequestData(new IncomingRequestData(ctx.req)); mwUtils.middlewareLog('Starting koa segment', ctx.url, segment); if (AWSXRay.isAutomaticMode()) { const ns = AWSXRay.getNamespace(); ns.bindEmitter(ctx.req); ns.bindEmitter(ctx.res); return ns.runAndReturn(async function () { let error; AWSXRay.setSegment(segment); ctx.segment = segment; try { if (next) { await next(); } } catch (err) { error = err; } exports._processResponse(ctx, segment, error); }); } else { let error; ctx.segment = segment; try { if (next) { await next(); } } catch (err) { error = err; } exports._processResponse(ctx, segment, error); } }; }, }; exports._processResponse = (ctx, segment, err) => { if (ctx.status >= 400) { if (ctx.status === 429) { segment.addThrottleFlag(); } segment[AWSXRay.utils.getCauseTypeFromHttpStatus(ctx.status)] = true; } if (segment.http && ctx.res) { segment.http.close(ctx.res); } segment.close(err); const message = err ? 'Closed koa segment with error' : 'Closed koa segment successfully'; mwUtils.middlewareLog(message, ctx.url, segment); if (err) { throw err; } }; module.exports = koaMW;