UNPKG

apminsight

Version:

monitor nodejs applications

132 lines (121 loc) 4.16 kB
var mod = require("module"); var coreModules = require("./core-modules"); var logger = require("./../util/logger"); var supportedModulesInfo = require("./npm-modules"); var wrapper = require("./wrapper"); var actLoad = mod._load; var modulesCacheInfo = {}; var supportedModules = Object.keys(supportedModulesInfo); function start() { instrumentCoreModules(); patchModuleLoad(); checkaddAsyncHooks(); } function instrumentCoreModules() { var modulesInfo = coreModules.MODULES_INFO; Object.keys(modulesInfo).forEach(function (moduleName) { logger.info("Instrumenting module::", moduleName); try { var actualModule = moduleName === "global" ? global : require(moduleName); } catch (err) { logger.info("module ::" + moduleName + " is not available"); return; } modulesInfo[moduleName].forEach(function (eachFunction) { wrapper.checkAndWrapFunction( actualModule, eachFunction, moduleName, eachFunction.functionName ); }); }); } /* eslint-disable no-unused-vars */ function patchModuleLoad() { mod._load = function (request, parent, Main) { var actualContent = actLoad.apply(this, arguments); if (supportedModules.indexOf(request) < 0) { return actualContent; } return checkAndInstrument(request, actualContent); }; } /* eslint-enable no-unused-vars */ function instrumentCustomModules(moduleName, moduleInfo) { supportedModulesInfo[moduleName] = moduleInfo; supportedModules.push(moduleName); } function checkAndInstrument(request, actualContent, moduleName) { if (modulesCacheInfo[request] && modulesCacheInfo[request].wrapped) { return modulesCacheInfo[request].wrapped; } logger.info("Instrumenting module::" + request); var functionInfo; if (moduleName) { var modInfo = supportedModulesInfo[moduleName]; functionInfo = modInfo[request]; } else { moduleName = request; functionInfo = supportedModulesInfo[moduleName]; } functionInfo.functions.forEach(function (eachFunction) { wrapper.checkAndWrapFunction( actualContent, eachFunction, moduleName, eachFunction.functionName ); }); modulesCacheInfo[request] = {}; modulesCacheInfo[request].wrapped = actualContent; return actualContent; } /* eslint-disable no-unused-vars */ function checkaddAsyncHooks() { try { var asyncHooks = require("async_hooks"); var contextMapping = {}; asyncHooks .createHook({ init: function initHook(id, type, triggerId, promiseWrap) { var curTxn = apmInsightAgentInstance.getCurTxn(); if (!curTxn || type !== "PROMISE") { return; } contextMapping[id] = { txn: curTxn, tracker: apmInsightAgentInstance.getCurTracker() }; }, before: function (id) { if (contextMapping[id]) { var context = contextMapping[id]; apmInsightAgentInstance.setCurContext( context.txn, context.tracker ); } }, after: function (id) { if (contextMapping[id]) { apmInsightAgentInstance.clearCurContext(); } }, destroy: function (id) { if (contextMapping[id]) { delete contextMapping[id]; } } }) .enable(); } catch (error) { logger.info("Async hook module is not available"); } } /* eslint-enable no-unused-vars */ module.exports = { start: start, instrumentCustomModules: instrumentCustomModules };