diff --git a/.travis.yml b/.travis.yml index ee28988..57fa076 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,10 @@ addons: packages: - g++-4.8 node_js: - - "6" - "8" - "10" + - "12" + - "14" install: - export CXX=g++-4.8 - $CXX --version diff --git a/example/childProcess.js b/example/childProcess.js index dd6e6db..b7b2077 100644 --- a/example/childProcess.js +++ b/example/childProcess.js @@ -7,21 +7,18 @@ spmAgent.on('metric', function (metric) { // if (metric.name === 'http') { // if (metric.name === 'numWorkers') { // if (metric.sct === 'APP') { - if ( - metric.name === 'process' || - metric.name === 'numWorkers' - ) { + if (metric.name === 'process' || metric.name === 'numWorkers') { console.log(metric) } }) spmAgent.on('metric', function (metric) { - if ( - metric.measurement === 'nodejs.process' - ) { - console.log(metric) - console.log('\n\n') - } + // if ( + // metric.measurement === 'nodejs.process' + // ) { + console.log(metric) + console.log('\n\n') + // } }) // if (process.send === undefined) { @@ -33,11 +30,13 @@ spmAgent.on('metric', function (metric) { const { resolve } = require('path') const { fork } = require('child_process') const http = require('http') -http.createServer(function (req, res) { - const longComputation = fork(resolve(__dirname, 'longComputation.js')) - longComputation.send('start') - longComputation.on('message', sum => { - res.end(String(sum)) - longComputation.kill(1) +http + .createServer(function (req, res) { + const longComputation = fork(resolve(__dirname, 'longComputation.js')) + longComputation.send('start') + longComputation.on('message', sum => { + res.end(String(sum)) + longComputation.kill(1) + }) }) -}).listen(4000) + .listen(4000) diff --git a/example/cluster.js b/example/cluster.js index 20c3158..a11b573 100644 --- a/example/cluster.js +++ b/example/cluster.js @@ -31,7 +31,7 @@ const masterProcess = () => { for (let i = 0; i < numCPUs; i++) { cluster.fork() - cluster.on('exit', (worker) => cluster.fork()) + cluster.on('exit', worker => cluster.fork()) } } const childProcess = () => { @@ -42,18 +42,22 @@ const childProcess = () => { // console.log(stats) }) spmAgent.on('metric', function (metric) { - if ( - // metric.name === 'process' || - metric.name === 'numWorkers' - ) { - console.log(metric) - } + // if ( + // metric.name === 'process' || + // metric.name === 'numWorkers' + // ) { + console.log(metric) + // } }) - console.log(`Worker${cluster.worker.id} running on port ${port} with pid ${cluster.worker.process.pid}`) - http.createServer(function (req, res) { - res.end('Hello World') - }).listen(port) + console.log( + `Worker${cluster.worker.id} running on port ${port} with pid ${cluster.worker.process.pid}` + ) + http + .createServer(function (req, res) { + res.end('Hello World') + }) + .listen(port) } if (cluster.isMaster) { diff --git a/lib/index.js b/lib/index.js index fc9b966..f19e28b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -27,7 +27,6 @@ function NodeJSAgent () { './eventLoopAgent.js', './gcAgent.js', './httpServerAgent.js', - './processAgent.js', './workerAgent.js' ] agentsToLoad.forEach(function (a) { diff --git a/lib/processAgent.js b/lib/processAgent.js deleted file mode 100644 index ceb6dc9..0000000 --- a/lib/processAgent.js +++ /dev/null @@ -1,185 +0,0 @@ -/* - * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved - * - * @licence SPM for NodeJS is free-to-use, proprietary software. - * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext) - * This source code may not be copied, reverse engineered, or altered for any purpose. - * This source code is to be used exclusively by users and customers of Sematext. - * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies. - */ -'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 = process.env.NODE_APP_INSTANCE !== undefined -const infraToken = Config.tokens.infra - -const getThreadCount = function (processId) { - let 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 { - const child = execProcess('powershell.exe', ['-Command', 'Get-CimInstance', '-Class Win32_Thread', '-Filter', `ProcessHandle = ${processId}`], { env: process.env }) - const 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) { - if (err) { - return console.error(err) - } - - const processes = Object.keys(results) - .map(key => results[key]) - .filter(proc => proc) - - const masterProcess = processes.filter(proc => proc.pid === pidToCheck).pop() - - const masterProcessMetric = { - timestamp: timestamp, - measurement: 'process', - tags: { - token: infraToken, - 'process.name': 'node', - 'process.type': 'master', - 'process.pid': masterProcess.pid, - 'process.ppid': masterProcess.ppid - }, - fields: { - 'thread.count': getThreadCount(pidToCheck), - 'cpu.usage': masterProcess.cpu, - rss: masterProcess.memory, - uptime: masterProcess.elapsed - } - } - agent.addMetrics(masterProcessMetric) - const childProcesses = processes.filter(proc => proc.pid !== pidToCheck) - if (childProcesses && childProcesses.length) { - childProcesses.forEach((proc, counter) => { - const childProcessMetric = { - timestamp: timestamp, - measurement: 'process', - tags: { - token: infraToken, - 'process.name': 'node', - 'process.type': 'child', - 'process.pid': proc.pid, - 'process.ppid': proc.ppid - }, - fields: { - 'thread.count': getThreadCount(proc.pid), - 'cpu.usage': proc.cpu, - rss: proc.memory, - uptime: proc.elapsed - } - } - agent.addMetrics(childProcessMetric) - }) - } - - const processCountMetric = { - timestamp: timestamp, - measurement: 'process', - tags: { - token: infraToken, - 'process.type': 'master', - 'process.name': 'node', - 'process.pid': masterProcess.pid, - 'process.ppid': masterProcess.ppid - }, - fields: { - count: 1 - } - } - agent.addMetrics(processCountMetric) - const processChildCountMetric = { - timestamp: timestamp, - measurement: 'process', - tags: { - token: infraToken, - 'process.type': 'child', - 'process.name': 'node', - 'process.pid': masterProcess.pid, - 'process.ppid': masterProcess.ppid - }, - fields: { - count: Math.max(processes.length - 1, 0) || 0 - } - } - agent.addMetrics(processChildCountMetric) - }) -} - -function getDefaultProcessMetrics (agent) { - if (process.send !== undefined) { - return // child process, not collecting stats - } - addMetrics(agent, process.pid) -} - -function getPm2Metrics (agent) { - if (process.send === undefined) { - return // master pm2 process, not collecting stats - } - addMetrics(agent, process.ppid) -} - -function getProcessStats () { - return { - start: function (agent) { - if (!infraToken) { - return - } - - this.timerId = setInterval(function () { - if (pm2Enabled) { - getPm2Metrics(agent) - } else { - getDefaultProcessMetrics(agent) - } - }, Config.collectionInterval) - if (this.timerId.unref) { - this.timerId.unref() - } - }, - stop: function () { - clearInterval(this.timerId) - } - } -} - -module.exports = function () { - const a = getProcessStats() - return new Agent(a) -} diff --git a/package-lock.json b/package-lock.json index fac644e..5fe7ca4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -152,9 +152,9 @@ }, "dependencies": { "@types/node": { - "version": "10.17.49", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.49.tgz", - "integrity": "sha512-PGaJNs5IZz5XgzwJvL/1zRfZB7iaJ5BydZ8/Picm+lUNYoNO9iVTQkVy5eUh0dZDrx3rBOIs3GCbCRmMuYyqwg==" + "version": "10.17.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.50.tgz", + "integrity": "sha512-vwX+/ija9xKc/z9VqMCdbf4WYcMTGsI0I/L/6shIF3qXURxZOhPQlPRHtjTpiNhAwn0paMJzlOQqw6mAGEQnTA==" }, "ws": { "version": "6.2.1", @@ -937,9 +937,9 @@ "dev": true }, "@types/js-yaml": { - "version": "3.12.5", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.5.tgz", - "integrity": "sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww==" + "version": "3.12.6", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.6.tgz", + "integrity": "sha512-cK4XqrLvP17X6c0C8n4iTbT59EixqyXL3Fk8/Rsk4dF3oX4dg70gYUXrXVUUHpnsGMPNlTQMqf+TVmNPX6FmSQ==" }, "@types/keyv": { "version": "3.1.1", @@ -3324,9 +3324,9 @@ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" }, "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-T0SnbxGiMcB09qd3bFcPt8rufxPs7T7TjePk33r1WsJNt12/rWsK/ofKqRHQ0rY/iMGE0mVdkc6Yg9CuL/ty0Q==" } } }, @@ -3749,9 +3749,9 @@ "dev": true }, "object-hash": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", - "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", + "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==" }, "object-inspect": { "version": "1.7.0", @@ -4458,11 +4458,18 @@ "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==" }, "pidusage": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.18.tgz", - "integrity": "sha512-Y/VfKfh3poHjMEINxU+gJTeVOBjiThQeFAmzR7z56HSNiMx+etl+yBhk42nRPciPYt/VZl8DQLVXNC6P5vH11A==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", "requires": { - "safe-buffer": "^5.1.2" + "safe-buffer": "^5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } } }, "pidusage-tree": { @@ -5298,9 +5305,9 @@ "dev": true }, "spm-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spm-agent/-/spm-agent-2.1.0.tgz", - "integrity": "sha512-4JkQ5Qbg/P1QHyFVZkFFWF8IqIzt67kG9feUqabgDke+oVBIJCRdAHlRd0rIqJI543pwhHfbLOgwj398YSEEfQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spm-agent/-/spm-agent-2.1.1.tgz", + "integrity": "sha512-wLHh/ZH6PFEHSf+8lQKHPZJDEmihIX1cMotx3EgRmkXCwh8BXLzoL/PZbsAy98ZmBN+2ziDZoFj72WdVULc3AA==", "requires": { "extend": "^3.0.2", "flat": "^2.0.1", @@ -5310,6 +5317,7 @@ "kubernetes-client": "^9.0.0", "moment": "^2.24.0", "nedb": "^1.8.0", + "pidusage-tree": "^2.0.5", "rc-yaml-2": "^1.0.2", "request": "^2.88.0", "winston": "^2.4.4" @@ -6048,9 +6056,9 @@ } }, "ws": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", - "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" }, "xdg-basedir": { "version": "4.0.0", diff --git a/package.json b/package.json index f8d06ec..328e73e 100644 --- a/package.json +++ b/package.json @@ -50,9 +50,8 @@ "dependencies": { "adm-zip": "^0.4.14", "measured-core": "^1.51.1", - "pidusage-tree": "^2.0.5", "request": "^2.88.0", - "spm-agent": "^2.1.0" + "spm-agent": "^2.1.1" }, "optionalDependencies": { "@sematext/gc-stats": "^1.5.2",