ca-apm-probe
Version:
CA APM Node.js Agent monitors real-time health and performance of Node.js applications
120 lines (88 loc) • 3.62 kB
JavaScript
/**
* Copyright (c) 2015 CA. All rights reserved.
*
* This software and all information contained therein is confidential and proprietary and
* shall not be duplicated, used, disclosed or disseminated in any way except as authorized
* by the applicable license agreement, without the express written permission of CA. All
* authorized reproductions must be marked with this language.
*
* EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE EXTENT
* PERMITTED BY APPLICABLE LAW, CA PROVIDES THIS SOFTWARE WITHOUT WARRANTY
* OF ANY KIND, INCLUDING WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL CA BE
* LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR
* INDIRECT, FROM THE USE OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, LOST
* PROFITS, BUSINESS INTERRUPTION, GOODWILL, OR LOST DATA, EVEN IF CA IS
* EXPRESSLY ADVISED OF SUCH LOSS OR DAMAGE.
*/
var path = require('path');
var agent = require('../agent');
var proxy = require('../proxy');
var util = require('util');
var logger = require("../logger");
var targetModule = new Object;
module.exports = function (Router) {
targetModule.router = Router;
targetModule.methodMap = getMethodsWithProbes();
// hook instrumentation on use event of koa-router
proxy.before(Router.prototype, 'use', instrumentKoaRouter);
// register call backs for methods of route stack
function instrumentKoaRouter(obj, args, storage) {
var router = args[1].router;
if (router && router.stack && router.stack.length) {
console.log(args[0]);
var stack = router.stack
for (var i = 0; i < stack.length; ++i) {
var layer = stack[i]
// hook each route
proxy.callback(layer.stack, 0, instrumentKoaRouterRoutes, null);
}
}
}
function instrumentKoaRouterRoutes(obj, args, storage) {
logger.debug('instrumenting koa-router middlewear call');
var res = args[0].res;
var req = args[0].req;
var eventNameFormatted = 'koa.route';
var ctx = storage.get('ctx') || req.__CA_ctx;
if (logger.isDebug()) {
if (ctx) {
logger.debug('%s[%d %d %d]: path - %s', eventNameFormatted, ctx.txid, ctx.lane, ctx.evtid, req.url);
}
else {
logger.debug('%s - no context', eventNameFormatted);
logger.debug((new Error('No context')).stack);
}
}
ctx = agent.asynchEventStart(ctx, eventNameFormatted, {
route: args[0]._matchedRoute,
http_method: req.method
});
storage.set('ctx', ctx);
var errorObject = new Object();
var end_save = res.end;
res.end = function () {
if (res.finished === false && ctx) {
ctx = agent.asynchEventDone(ctx, eventNameFormatted, null,
errorObject);
if (ctx) {
agent.asynchEventFinish(ctx);
}
}
end_save.apply(res, arguments);
};
}
};
function getMethodsWithProbes() {
if (!targetModule.methodMap) {
var mt = new Object;
mt[0] = 'koa#route';
targetModule.methodMap = mt;
}
return targetModule.methodMap;
}
function instrument(methodMap) {
targetModule.methodMap = methodMap;
}
module.exports.getMethodsWithProbes = getMethodsWithProbes;
module.exports.instrument = instrument.bind(module);