UNPKG

apminsight

Version:

monitor nodejs applications

321 lines (301 loc) 10.1 kB
var metricstore = require("./../metrics/metricstore"); var constants = require("./../constants"); var webTxn = require("./../metrics/webtxn"); var logger = require("./../util/logger"); var utils = require("./../util/utils"); var tracker = require("./../metrics/tracker"); var nvmStats = require("./../metrics/nodevm"); function getTxnMetric() { var metricArray = []; var insDbMetric = {}; var insApdexRTMetric = new webTxn({}); processTxnMetric( metricstore.getWebTxnMetric(), constants.webTxnPrefix, constants.apdex, metricArray, insDbMetric, insApdexRTMetric ); if (metricArray.length > 0) { appendTxnApdexRtMetric( insApdexRTMetric, "", constants.apdex, metricArray ); checkAndAppendDbMetric(insDbMetric, "", metricArray); } processTxnMetric( metricstore.getBgTxnmetric(), constants.bgTxnPrefix, constants.bckgrnd, metricArray, insDbMetric ); processAppMetric(metricArray); logger.info("total metric collected " + metricArray.length); return metricArray; } function processTxnMetric( txnMetric, nsPrefix, name, metricArray, insDbMetric, insApdexRTMetric ) { var allUniqueTxn = Object.keys(txnMetric); allUniqueTxn.forEach(function (txnName) { var txn = txnMetric[txnName]; if (!txn) { logger.critical("empty txn present in data store"); return; } var ns = nsPrefix + txn.getUrl(); appendTxnApdexRtMetric(txn, ns, name, metricArray, insApdexRTMetric); aggregateAndAppendDbMetric(txn, ns, metricArray, insDbMetric); }); } function appendTxnApdexRtMetric(txn, ns, name, metricArray, insApdexRTMetric) { var info = { ns: ns, name: name }; var txnData = txn.getFormattedRtData(); var metric = [info, txnData]; metricArray.push(metric); if (insApdexRTMetric) { insApdexRTMetric.aggregate(txn); } } function aggregateAndAppendDbMetric(txn, ns, metricArray, insDbMetric) { var dbMetric = {}; txn.getDbCalls().forEach(function (dbTracker) { var info = dbTracker.extractOperationInfo(); if (utils.isEmpty(info.opn) || utils.isEmpty(info.object)) { return; } var dbOpn = "db/" + info.opn + "/" + info.object + "/dummy-db"; var matchedDbOpn = dbMetric[dbOpn] || new tracker.DbTracker({}); matchedDbOpn.aggregate(dbTracker); dbMetric[dbOpn] = matchedDbOpn; }); checkAndAppendDbMetric(dbMetric, ns, metricArray, insDbMetric); } function checkAndAppendDbMetric(dbMetric, ns, metricArray, insDbMetric) { Object.keys(dbMetric).forEach(function (eachUniqueDbOpn) { var eachDbMetric = dbMetric[eachUniqueDbOpn]; var info = eachDbMetric.extractOperationInfo(); if (utils.isEmpty(info.opn) || utils.isEmpty(info.object)) { return; } var metric = getDbMetric(eachDbMetric, ns, eachUniqueDbOpn); if (insDbMetric) { var opnName = "db/" + info.opn + "/all/dummy-db"; aggregateDbByOpnWise(insDbMetric, opnName, eachDbMetric); aggregateDbByOpnWise( insDbMetric, constants.dbOpnOverAll, eachDbMetric ); } metricArray.push(metric); }); } function aggregateDbByOpnWise(insDbMetric, dbOpn, eachDbMetric) { var matchedDbOpn = insDbMetric[dbOpn] || new tracker.DbTracker({}); matchedDbOpn.aggregate(eachDbMetric); insDbMetric[dbOpn] = matchedDbOpn; } function getDbMetric(dbTracker, ns, name) { var info = { ns: ns, name: name }; var rtData = [ dbTracker.getTime(), dbTracker.getMinRt(), dbTracker.getMaxRt(), dbTracker.getCount(), dbTracker.getErrorCount() ]; return [info, rtData]; } function processAppMetric(metricArray) { formatAppMetricSum(metricArray); formatAppMetricAvg(metricArray); } function formatAppMetricSum(metricArray) { var appMetricSum = metricstore.getAppMetricSum(); var allAppMetrics = Object.keys(appMetricSum); if (allAppMetrics.length <= 0) { return; } var info = { ns: constants.appParam, name: constants.sumStr }; var data = [[appMetricSum]]; metricArray.push([info, data]); } function formatAppMetricAvg(metricArray) { var appMetricAvg = metricstore.getAppMetricAvg(); var allAppMetrics = Object.keys(appMetricAvg); if (allAppMetrics.length <= 0) { return; } var formattedAppMetricAvg = {}; allAppMetrics.forEach(function (eachAppMetric) { var metricInfo = appMetricAvg[eachAppMetric]; var data = [ metricInfo.total, metricInfo.min, metricInfo.max, metricInfo.count, 0 ]; formattedAppMetricAvg[eachAppMetric] = data; }); var info = { ns: constants.appParam, name: constants.avgStr }; var data = [[formattedAppMetricAvg]]; metricArray.push([info, data]); } function getFormattedTraceData() { var allTraceData = []; var ignoreCount = 0; var traceList = metricstore.getTraceMetric(); logger.info("number of trace collected::" + traceList.length); traceList.forEach(function (txn) { var traceInfo = txn.getTraceInfo(); var traceData = getTraceData(txn, traceInfo); allTraceData.push([traceInfo, traceData]); }); logger.info("number of trace ignored:: " + ignoreCount); return allTraceData; } function getTraceData(txn, traceInfo) { var allTrackerData = []; var childTrackersData = []; var rootTrackersData = []; var rootTracker = txn.getRootTracker(); var allChildTrackers = rootTracker.getChildTrackers(); for (var index = 0; index < allChildTrackers.length; index++) { var curChildTracker = allChildTrackers[index]; traverseTracker(txn, curChildTracker, traceInfo, childTrackersData); } appendSummaryTrackerInfo(allTrackerData, txn, traceInfo); appendRootTrackerInfo(rootTrackersData, rootTracker); rootTrackersData.push(childTrackersData); allTrackerData.push([rootTrackersData]); return allTrackerData; } function appendSummaryTrackerInfo(allTrackerData, txn, traceInfo) { const rootTracker = txn.getRootTracker(); allTrackerData.push(rootTracker.getStartTime()); let totalMethodsCount = traceInfo.method_count - traceInfo.sql_trackers_count - traceInfo.loginfo.length; let summary = `Total Call(s): ${totalMethodsCount} Method Call(s) `; if(traceInfo.sql_trackers_count > 0){ summary += `+ ${traceInfo.sql_trackers_count} SQL(s)`; } if(traceInfo.loginfo.length > 0){ summary += `+ ${traceInfo.loginfo.length} Other exception(s)`; } allTrackerData.push(summary); allTrackerData.push("SUMMARY"); allTrackerData.push(traceInfo.r_time); allTrackerData.push(0); allTrackerData.push(null); } function appendRootTrackerInfo(rootTrackersData, rootTracker) { rootTrackersData.push(rootTracker.getStartTime()); rootTrackersData.push(rootTracker.getTrackerNameForTrace()); rootTrackersData.push(rootTracker.getComponent()); rootTrackersData.push(rootTracker.getTime() + rootTracker.getChildOverhead()); rootTrackersData.push(rootTracker.getTime()); rootTrackersData.push(null); } function traverseTracker( txn, baseTracker, traceInfo, childTrackersData, curTrackerInfo ) { if (!baseTracker || traceInfo.method_count > constants.maxTrackers) { return; } curTrackerInfo = checkAndIncludeTracker( txn, baseTracker, traceInfo, childTrackersData, curTrackerInfo ); var allChildTrackers = baseTracker.getChildTrackers(); for (var index = 0; index < allChildTrackers.length; index++) { var curChildTracker = allChildTrackers[index]; traverseTracker( txn, curChildTracker, traceInfo, childTrackersData, curTrackerInfo ); } } function checkAndIncludeTracker( txn, tracker, traceInfo, trackerData, curTrackerInfo ) { if (tracker.isAllowedInTrace(txn)) { var tempTrackerInfo = getTrackerInfo(txn, tracker, traceInfo); if (curTrackerInfo) { curTrackerInfo[6].push(tempTrackerInfo); } else { trackerData.push(tempTrackerInfo); } if (tracker.isDistributedTrace()) { traceInfo.dt_count++; } traceInfo.method_count++; return tempTrackerInfo; } return curTrackerInfo; } function getTrackerInfo(txn, tracker, traceInfo) { var trackerInfo = [ tracker.getStartTime(), tracker.getTrackerNameForTrace(), tracker.getComponent(), tracker.getTime(), tracker.getTime(), tracker.getAdditionalInfo(txn), [] ]; if (tracker.isDbTracker) { var info = tracker.extractOperationInfo(); if (info.opn && info.object) { var opnInfo = info.opn + "/" + info.object; if (traceInfo.db_opn.indexOf(opnInfo) < 0) { traceInfo.db_opn.push(opnInfo); } } } if ( tracker.isError() && traceInfo.loginfo.length < constants.maxExcPerTrace ) { var errorInfo = tracker.getErrorInfo(); var eachLogInfo = {}; eachLogInfo.time = errorInfo.getTime(); eachLogInfo.level = errorInfo.getLevel(); eachLogInfo.str = errorInfo.getMessage(); eachLogInfo.err_clz = errorInfo.getType(); eachLogInfo.st = errorInfo.getErrorStackFrames(); traceInfo.loginfo.push(eachLogInfo); } return trackerInfo; } function getNVMMetrics() { return nvmStats.getNodeVMStats(); } module.exports = { getTxnMetric: getTxnMetric, getFormattedTraceData: getFormattedTraceData, getNodeVMMetrics: getNVMMetrics };