diff --git a/lib/processAgent.js b/lib/processAgent.js index 5478b7e..5dc5d6d 100644 --- a/lib/processAgent.js +++ b/lib/processAgent.js @@ -10,9 +10,50 @@ 'use strict' const { Agent, Config } = require('spm-agent') const pidUsageTree = require('pidusage-tree') +const fs = require('fs') +const execProcess = require('child_process').spawnSync const pm2Enabled = /^true/i.test(process.env.PM2) const infraToken = Config.tokens.infra +const getThreadCount = function (processId) { + // thread count meric + var threadCount = 0 + if (/linux/i.test(process.platform)) { + try { + const pidStatus = String(fs.readFileSync(`/proc/${processId}/status`)) + const threadCountLine = pidStatus.match(/Threads:\s(\d+)/) + if (threadCountLine && threadCountLine.length > 1) { + threadCount = Number(threadCountLine[1]) + } + } catch (err) { + // console.error(err) + } + } + if (/win/i.test(process.platform)) { + try { + var child = execProcess('powershell.exe', ['-Command', 'Get-CimInstance', '-Class Win32_Thread', '-Filter', `ProcessHandle = ${processId}`], { env: process.env }) + var tc = Number(String(child.stdout)) + if (tc) { + threadCount = tc + } + } catch (winErr) { + console.error(winErr) + } + } + if (/darwin/i.test(process.platform)) { + try { + const child = execProcess('/bin/ps', ['M', `${processId}`], { env: process.env }) + const darwinTc = (String(child.stdout) || '').split('\n').length + if (darwinTc > 0) { + threadCount = darwinTc - 1 // remove headline + } + } catch (darwinErr) { + // console.error(darwinErr) + } + } + return threadCount +} + const addMetrics = function (agent, pidToCheck) { const timestamp = new Date() pidUsageTree(pidToCheck, function (err, results) { @@ -34,6 +75,7 @@ const addMetrics = function (agent, pidToCheck) { 'process.type': 'master' }, fields: { + 'thread.count': getThreadCount(pidToCheck), 'cpu.usage': masterProcess.cpu, rss: masterProcess.memory, uptime: masterProcess.elapsed @@ -52,6 +94,7 @@ const addMetrics = function (agent, pidToCheck) { 'process.type': 'child' }, fields: { + 'thread.count': getThreadCount(proc.id), 'cpu.usage': proc.cpu, rss: proc.memory, uptime: proc.elapsed diff --git a/test/test.js b/test/test.js index c70f2ce..7a47ff5 100644 --- a/test/test.js +++ b/test/test.js @@ -184,10 +184,10 @@ describe('SPM for Node.js tests', function () { } if (metric.measurement && metric.measurement.indexOf('process') > -1 && metric.fields.uptime && - metric.fields.memory && - metric.fields['cpu.usage']) { + metric.fields.rss && + metric.fields['cpu.usage'] && + metric.fields['thread.count']) { if (metric.tags.token !== config.tokens.infra) { - console.log(metric) done(new Error(`No infra token set ${metric.tags.token} != ${config.tokens.infra}`)) errorReported = true } @@ -195,14 +195,13 @@ describe('SPM for Node.js tests', function () { } if (metric.measurement && metric.measurement.indexOf('process') > -1 && metric.fields.count) { if (metric.tags.token !== config.tokens.infra) { - console.log(metric) done(new Error(`No infra token set ${metric.tags.token} != ${config.tokens.infra}`)) errorReported = true } metricCounter = metricCounter + 1 } - if (metricCounter > 1) { + if (metricCounter > 2) { agent.removeListener('metric', checkMetrics) agent.stop() done()