apminsight
Version:
monitor nodejs applications
193 lines (180 loc) • 5.26 kB
JavaScript
// supported upto 4.6.2
var wrapper = require("./../wrapper");
var utils = require("./../../util/utils");
var moduleName = "Express",
middleWare = "Middleware";
var moduleInfo = {
functions: [
{
functionName: "application.render",
component: moduleName
},
{
functionName: "response.json",
component: moduleName,
sync: true
},
{
functionName: "response.jsonp",
component: moduleName,
sync: true
},
{
functionName: "response.redirect",
component: moduleName,
sync: true,
extractInfo: getRedirectUrl
},
{
// internally calls the app.render, so may be not needed to instrument
functionName: "response.render",
component: moduleName
},
{
functionName: "response.send",
component: moduleName,
extractInfo: addBytesOut
},
{
functionName: "response.sendFile",
component: moduleName
}
]
};
var innerModules = ["application", "Router"];
var routingMethods = [
"checkout",
"copy",
"delete",
"get",
"head",
"lock",
"merge",
"mkactivity",
"mkcol",
"move",
"m-search",
"notify",
"options",
"patch",
"post",
"purge",
"put",
"report",
"search",
"subscribe",
"trace",
"unlock",
"unsubscribe",
"use",
"all",
"param"
];
innerModules.forEach(function (eachModules) {
routingMethods.forEach(function (eachRoutingMethods) {
var functionInfo = {};
functionInfo.functionName = eachModules + "." + eachRoutingMethods;
functionInfo.wrapper = wrapMiddleWare;
functionInfo.component = middleWare;
moduleInfo.functions.push(functionInfo);
});
});
function wrapMiddleWare(actual) {
return function () {
// check and wrap handlers
if (arguments) {
for (var index = 0; index < arguments.length; index++) {
if (arguments[index] && utils.isFunction(arguments[index])) {
arguments[index] = wrapHandler(arguments[index]);
} else if (Array.isArray(arguments[index])) {
arguments[index] = checkAndWrapArrayArguments(
arguments[index]
);
}
}
}
return actual.apply(this, arguments);
};
}
function checkAndWrapArrayArguments(args) {
var wrappedArgs;
if (args) {
wrappedArgs = [];
for (var index = 0; index < args.length; index++) {
if (args[index] && utils.isFunction(args[index])) {
wrappedArgs.push(wrapHandler(args[index]));
} else if (Array.isArray(args[index])) {
wrappedArgs.push(checkAndWrapArrayArguments(args[index]));
} else {
wrappedArgs.push(args[index]);
}
}
}
return wrappedArgs;
}
/* eslint-disable no-unused-vars */
function wrapHandler(handler) {
if (handler.length > 3) {
return function (err, req, res, next) {
return handleMiddleware(this, handler, arguments);
};
}
return function (req, res, next) {
return handleMiddleware(this, handler, arguments);
};
}
/* eslint-enable no-unused-vars */
function handleMiddleware(invoker, handler, args) {
var curTxn = apmInsightAgentInstance.getCurTxn();
if (!curTxn || curTxn.isCompleted()) {
return handler.apply(invoker, args);
}
var parentTracker = apmInsightAgentInstance.getCurTracker();
var handlerName = handler.name ? handler.name : "Anonymous";
var trackerName = "Express - Middleware -" + handlerName;
var trackerInfo = {
trackerName: trackerName,
component: middleWare,
sync: true
};
var syncOpnInfo = {
txn: curTxn,
syncParentTracker: parentTracker,
trackerInfo: trackerInfo
};
wrapper.invokeSyncOpn(handler, invoker, args, syncOpnInfo);
}
/* eslint-disable no-unused-vars */
function getRedirectUrl(invoker, params, returnObj, tracker, asyncOpnInfo) {
if (!params || params.length == 0) {
return;
}
var info = {};
if (params[0] && typeof params[0] === "string") {
info.url = params[0];
} else if (
params.length > 1 &&
params[1] &&
typeof params[1] === "string"
) {
info.url = params[1];
}
tracker.updateInfo(info);
}
function addBytesOut(invoker, params, returnObj, tracker, asyncOpnInfo) {
var bytesOut = 0;
var txn = apmInsightAgentInstance.getCurTxn();
var data = params[0];
if (txn && !txn.isCompleted()) {
if (Buffer.isBuffer(params[0]) || utils.isBoolean(params[0])) {
data = params[0].toString();
}
if (utils.isObject(params[0])) {
data = JSON.stringify(params[0]);
}
bytesOut += utils.isNonEmptyString(data) ? Buffer.byteLength(data) : 0;
txn.setBytesOut(bytesOut);
}
}
/* eslint-enable no-unused-vars */
module.exports = moduleInfo;