Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pidusage

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pidusage - npm Package Compare versions

Comparing version 1.1.6 to 1.2.0

truc.js

34

index.js
var os = require('os')
var stats = require('./lib/stats')
var wrapper = function(stat_type) {
return function(pid, options, cb) {
if(typeof options == 'function') {
var wrapper = function (statType) {
return function (pid, options, cb) {
if (typeof options === 'function') {
cb = options

@@ -13,3 +11,3 @@ options = {}

return stats[stat_type](pid, options, cb)
return stats[statType](pid, options, cb)
}

@@ -26,4 +24,4 @@ }

aix: wrapper('ps'),
unsupported: function(pid, options, cb) {
cb = typeof options == 'function' ? options : cb
unsupported: function (pid, options, cb) {
cb = typeof options === 'function' ? options : cb

@@ -34,14 +32,14 @@ cb(new Error(os.platform() + ' is not supported yet, please fire an issue (https://github.com/soyuka/pidusage)'))

var platform = os.platform();
platform = platform.match(/^win/) ? 'win' : platform; //nor is windows a winner...
platform = pusage[platform] ? platform : 'unsupported';
var platform = os.platform()
platform = platform.match(/^win/) ? 'win' : platform // nor is windows a winner...
platform = pusage[platform] ? platform : 'unsupported'
exports.stat = function() {
pusage[platform].apply(stats, [].slice.call(arguments));
};
exports.stat = function () {
pusage[platform].apply(stats, [].slice.call(arguments))
}
exports.unmonitor = function(pid) {
delete stats.history[pid];
};
exports.unmonitor = function (pid) {
delete stats.history[pid]
}
exports._history = stats.history;
exports._history = stats.history
var os = require('os')
, exec = require('child_process').exec
var exec = require('child_process').exec
module.exports = {
getconf: function(keyword, options, next) {
if(typeof options == 'function') {
getconf: function (keyword, options, next) {
if (typeof options === 'function') {
next = options

@@ -12,5 +11,5 @@ options = { default: '' }

exec('getconf '+keyword, function(error, stdout, stderr) {
if(error !== null) {
console.error('Error while getting '+keyword, error)
exec('getconf ' + keyword, function (error, stdout, stderr) {
if (error !== null) {
console.error('Error while getting ' + keyword, error)
return next(null, options.default)

@@ -21,3 +20,3 @@ }

if(!isNaN(stdout)) {
if (!isNaN(stdout)) {
return next(null, stdout)

@@ -29,17 +28,23 @@ }

},
cpu: function(next) {
cpu: function (next) {
var self = this
self.getconf('CLK_TCK', {default: 100}, function(err, clock_tick) {
self.getconf('PAGESIZE', {default: 4096}, function(err, pagesize) {
self.getconf('CLK_TCK', {default: 100}, function (err, clockTick) {
if (err) {
return next(err)
}
self.getconf('PAGESIZE', {default: 4096}, function (err, pagesize) {
if (err) {
return next(err)
}
next(null, {
clock_tick: clock_tick,
clockTick: clockTick,
uptime: os.uptime(),
pagesize: pagesize
})
})
})
})
}
}

@@ -8,16 +8,17 @@ var os = require('os')

var format = require('util').format
var PLATFORM = os.platform()
var stats = {
history: {},
cpu: null, //used to store cpu informations
proc: function(pid, options, done) {
cpu: null, // used to store cpu informations
proc: function (pid, options, done) {
var self = this
if(this.cpu !== null) {
fs.readFile('/proc/uptime', 'utf8', function(err, uptime) {
if(err) {
if (this.cpu !== null) {
fs.readFile('/proc/uptime', 'utf8', function (err, uptime) {
if (err) {
return done(err, null)
}
if(uptime === undefined) {
if (uptime === undefined) {
console.error("[pidusage] We couldn't find uptime from /proc/uptime")

@@ -32,4 +33,4 @@ self.cpu.uptime = os.uptime()

} else {
helpers.cpu(function(err, cpu) {
if(err) {
helpers.cpu(function (err, cpu) {
if (err) {
return done(err, null)

@@ -43,3 +44,3 @@ }

},
proc_calc: function(pid, options, done) {
proc_calc: function (pid, options, done) {
pid = parseInt(pid, 10)

@@ -50,36 +51,34 @@ var history = this.history[pid] ? this.history[pid] : {}

//Arguments to path.join must be strings
fs.readFile(p.join('/proc', ''+pid, 'stat'), 'utf8', function(err, infos) {
if(err) {
// Arguments to path.join must be strings
fs.readFile(p.join('/proc', '' + pid, 'stat'), 'utf8', function (err, infos) {
if (err) {
return done(err, null)
}
//https://github.com/arunoda/node-usage/commit/a6ca74ecb8dd452c3c00ed2bde93294d7bb75aa8
//preventing process space in name by removing values before last ) (pid (name) ...)
// https://github.com/arunoda/node-usage/commit/a6ca74ecb8dd452c3c00ed2bde93294d7bb75aa8
// preventing process space in name by removing values before last ) (pid (name) ...)
var index = infos.lastIndexOf(')')
infos = infos.substr(index + 2).split(' ')
//according to http://man7.org/linux/man-pages/man5/proc.5.html (index 0 based - 2)
//In kernels before Linux 2.6, start was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks
// according to http://man7.org/linux/man-pages/man5/proc.5.html (index 0 based - 2)
// In kernels before Linux 2.6, start was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks
var stat = {
utime: parseFloat(infos[11]),
stime: parseFloat(infos[12]),
cutime: parseFloat(infos[13]),
cstime: parseFloat(infos[14]),
start: parseFloat(infos[19]) / cpu.clock_tick,
rss: parseFloat(infos[21])
utime: parseFloat(infos[11]),
stime: parseFloat(infos[12]),
cutime: parseFloat(infos[13]),
cstime: parseFloat(infos[14]),
start: parseFloat(infos[19]) / cpu.clockTick,
rss: parseFloat(infos[21])
}
//http://stackoverflow.com/questions/16726779/total-cpu-usage-of-an-application-from-proc-pid-stat/16736599#16736599
// http://stackoverflow.com/questions/16726779/total-cpu-usage-of-an-application-from-proc-pid-stat/16736599#16736599
var childrens = options.childrens ? stat.cutime + stat.cstime : 0
var total = stat.stime - (history.stime || 0) + stat.utime - (history.utime || 0) + childrens
total = total / cpu.clock_tick
total = total / cpu.clockTick
//time elapsed between calls
// time elapsed between calls
var seconds = history.uptime !== undefined ? cpu.uptime - history.uptime : stat.start - cpu.uptime
seconds = Math.abs(seconds)
seconds = seconds === 0 ? 1 : seconds //we sure can't divide through 0
seconds = seconds === 0 ? 1 : seconds // we sure can't divide through 0

@@ -89,5 +88,17 @@ self.history[pid] = stat

var cpuPercent = (total / seconds) * 100
var memory = stat.rss * cpu.pagesize
if (!options.advanced) {
return done(null, {
cpu: cpuPercent,
memory: memory
})
}
return done(null, {
cpu: (total / seconds) * 100,
memory: stat.rss * cpu.pagesize
cpu: cpuPercent,
memory: memory,
time: stat.utime + stat.stime,
start: stat.start
})

@@ -104,12 +115,20 @@ })

*/
ps: function(pid, options, done) {
ps: function (pid, options, done) {
pid = parseInt(pid, 10)
var cmd = 'ps -o pcpu,rss -p '
if(os.platform() == 'aix')
cmd = 'ps -o pcpu,rssize -p ' //this one could work on other platforms
if (options.advanced) {
cmd = 'ps -o pcpu,rss,time,start -p '
exec(cmd + pid, function(err, stdout, stderr) {
if(err)
if (PLATFORM === 'aix') {
cmd = 'ps -o pcpu,rssize,time,start -p '
}
} else if (PLATFORM === 'aix') {
cmd = 'ps -o pcpu,rssize -p ' // this one could work on other platforms see AIX section in man ps
}
exec(cmd + pid, function (err, stdout, stderr) {
if (err) {
return done(err, null)
}

@@ -119,5 +138,17 @@ stdout = stdout.split(os.EOL)[1]

var cpuPercent = parseFloat(stdout[0].replace(',', '.'))
var memory = parseFloat(stdout[1]) * 1024
if (!options.advanced) {
return done(null, {
cpu: cpuPercent,
memory: memory
})
}
return done(null, {
cpu: parseFloat(stdout[0].replace(',', '.')),
memory: parseFloat(stdout[1]) * 1024
cpu: cpuPercent,
memory: memory,
time: parseFloat(stdout[2]),
start: parseFloat(stdout[3])
})

@@ -129,6 +160,6 @@ })

*/
win: function(pid, options, done) {
win: function (pid, options, done) {
pid = parseInt(pid, 10)
var history = this.history[pid] ? this.history[pid] : {}
// http://social.msdn.microsoft.com/Forums/en-US/469ec6b7-4727-4773-9dc7-6e3de40e87b8/cpu-usage-in-for-each-active-process-how-is-this-best-determined-and-implemented-in-an?forum=csharplanguage
// http://social.msdn.microsoft.com/Forums/en-US/469ec6b7-4727-4773-9dc7-6e3de40e87b8/cpu-usage-in-for-each-active-process-how-is-this-best-determined-and-implemented-in-an?forum=csharplanguage
var args = 'PROCESS ' + pid + ' get workingsetsize,usermodetime,kernelmodetime'

@@ -143,19 +174,19 @@

wmic.stdout.on('data', function(d) {
stdout += d.toString()
wmic.stdout.on('data', function (d) {
stdout += d.toString()
})
wmic.stderr.on('data', function(d) {
wmic.stderr.on('data', function (d) {
stderr += d.toString()
})
wmic.on('error', function(err) {
wmic.on('error', function (err) {
console.error('[pidusage] Command "wmic ' + args + '" failed with error %s', err)
})
wmic.on('close', function(code) {
wmic.on('close', function (code) {
stdout = stdout.trim()
stderr = stderr.trim()
if(!stdout || code !== 0) {
if (!stdout || code !== 0) {
var error = format('%s Wmic errored, please open an issue on https://github.com/soyuka/pidusage with this message.%s', new Date().toString(), os.EOL)

@@ -165,3 +196,3 @@ error += format('Command was "wmic %s" %s System informations: %s - release: %s %s - type %s %s', args, os.EOL, os.EOL, os.release(), os.EOL, os.type(), os.EOL)

stderr = format('%s%s%sWmic exited with code %d.', os.EOL, stderr, os.EOL, code)
stderr = format('%s%sStdout was %s', stderr, os.EOL, stdout ? stdout : 'empty')
stderr = format('%s%sStdout was %s', stderr, os.EOL, stdout || 'empty')

@@ -175,3 +206,3 @@ return done(new Error(stderr, null))

kernelmodetime: parseFloat(stdout[0]),
usermodetime: parseFloat(stdout[1]),
usermodetime: parseFloat(stdout[1])
}

@@ -181,7 +212,7 @@

//process usage since last call
// process usage since last call
var total = stats.kernelmodetime - (history.kernelmodetime || 0) + stats.usermodetime - (history.usermodetime || 0)
total = total / 10000000
//time elapsed between calls
// time elapsed between calls
var seconds = history.uptime !== undefined ? uptime - history.uptime : 0

@@ -198,3 +229,12 @@

return done(null, {cpu: cpu, memory: workingsetsize})
if (!options.advanced) {
return done(null, {cpu: cpu, memory: workingsetsize})
}
return done(null, {
cpu: cpu,
memory: workingsetsize,
time: stats.usermodetime + stats.kernelmodetime,
start: seconds
})
})

@@ -205,2 +245,2 @@ wmic.stdin.end()

module.exports = stats;
module.exports = stats
{
"name": "pidusage",
"version": "1.1.6",
"version": "1.2.0",
"description": "Cross-platform process cpu % and memory usage of a PID — Edit",

@@ -10,3 +10,4 @@ "main": "index.js",

"mocha": "~2.3.4",
"mockery": "1.4.0"
"mockery": "1.4.0",
"standard": "^10.0.3"
},

@@ -17,3 +18,3 @@ "engines": {

"scripts": {
"test": "mocha test/test.js --reporter min && node test/stresstest.js"
"test": "standard index.js lib/*.js test/*.js && mocha test/test.js --reporter min && node test/stresstest.js"
},

@@ -20,0 +21,0 @@ "repository": {

@@ -18,4 +18,7 @@ pidusage

pusage.stat(process.pid, function(err, stat) {
// Compute statistics every second:
setInterval(function () {
pusage.stat(process.pid, function (err, stat) {
expect(err).to.be.null

@@ -29,8 +32,32 @@ expect(stat).to.be.an('object')

})
})
}, 1000)
// Unmonitor process
```
When you're done with the given `pid`, you may want to clear `pidusage` history (it only keeps the last stat values):
```
pusage.unmonitor(process.pid);
```
### Advanced mode
If you need raw data you can use the advanced mode since 1.2.0:
```javascript
pusage(process.pid, {advanced: true}, function (err, stat) {
console.log(stat.time, stat.start)
})
```
The `stat` object will contain the following:
```
- `cpu` cpu percent
- `memory` memory bytes
- `time` user + system time
- `start` time process was started
```
## How it works

@@ -43,3 +70,3 @@

/!\ As stated in [#17](https://github.com/soyuka/pidusage/issues/17), memory will increase when using `pidusage.stat` in an interval because of `readFile`. Use `--expose-gc` and release the garbage collector to avoid such leaking.
/!\ As stated in [#17](https://github.com/soyuka/pidusage/issues/17), memory will increase when using `pidusage.stat` in an interval because of `readFile`. It will naturally be released by the garbage collector.

@@ -78,3 +105,3 @@ Cpu usage is computed by following [those instructions](http://stackoverflow.com/questions/16726779/how-do-i-get-the-total-cpu-usage-of-an-application-from-proc-pid-stat/16736599#16736599). It keeps an history of the current processor time for the given pid so that the computed value gets more and more accurate. Don't forget to do `unmonitor(pid)` so that history gets cleared.

If you want to compute a pidusage tree take a look at [pidusage-tree](https://github.com/soyuka/pidusage-tree).
If you want to compute a pidusage tree take a look at [pidusage-tree](https://github.com/soyuka/pidusage-tree).

@@ -81,0 +108,0 @@ ## Licence

@@ -1,11 +0,15 @@

var http = require('http'), pusage = require('../')
var http = require('http')
var pusage = require('../')
http.createServer(function(req, res) {
http.createServer(function (req, res) {
res.writeHead(200)
res.end("hello world\n")
res.end('hello world\n')
}).listen(8020)
var interval = setInterval(function () {
console.log('\033[2J')
pusage.stat(process.pid, function(err, stat) {
pusage.stat(process.pid, function (err, stat) {
if (err) {
throw err
}
console.log(stat)

@@ -15,4 +19,4 @@ })

process.on('exit', function() {
clearInterval(interval)
process.on('exit', function () {
clearInterval(interval)
})
var pusage = require('../')
//stress test to compare with top or another tool
// stress test to compare with top or another tool
console.log('This is my PID: %s', process.pid)
//classic "drop somewhere"... yeah I'm a lazy guy
var formatBytes = function(bytes, precision) {
// classic "drop somewhere"... yeah I'm a lazy guy
var formatBytes = function (bytes, precision) {
var kilobyte = 1024

@@ -28,11 +28,10 @@ var megabyte = kilobyte * 1024

var i = 0, big_memory_leak = []
var i = 0
var bigMemoryLeak = []
var stress = function(cb) {
var stress = function (cb) {
var j = 500
var arr = []
// console.log('\033[2J')
var j = 500, arr = []
while(j--) {
while (j--) {
arr[j] = []

@@ -45,42 +44,42 @@

big_memory_leak.push(arr)
bigMemoryLeak.push(arr)
pusage.stat(process.pid, function(err, stat) {
pusage.stat(process.pid, function (err, stat) {
if (err) {
throw err
}
console.log('Pcpu: %s', stat.cpu)
console.log('Mem: %s', formatBytes(stat.memory))
//this is to compare with node-usage results, but it's broken on v11.12
// require('usage').lookup(process.pid, {keepHistory: true}, function(err, stat) {
// console.log('Usage Pcpu: %s', stat.cpu)
// console.log('Usage Mem: %s', formatBytes(stat.memory))
if (i === 100) {
return cb(null, true)
} else if (stat.memory > 3e8) {
console.log("That's enough right?")
cb(null, true)
}
if(i == 100)
return cb(true)
// else if(stat.memory > 209715200) {
else if(stat.memory > 5e8) {
console.log("That's enough right?")
cb(true)
}
i++
return cb(false)
// })
i++
return cb(null, false)
})
}
var interval = function() {
return setTimeout(function() {
var interval = function () {
return setTimeout(function () {
stress(function (err, stop) {
if (err) {
throw err
}
stress(function(stop) {
if(stop)
if (stop) {
process.exit()
else
} else {
return interval()
}
})
}, 400)
}
setTimeout(function() {
setTimeout(function () {
interval()
}, 2000)

@@ -1,31 +0,31 @@

var mockery = require('mockery'),
expect = require('chai').expect,
os = require('os')
/* global beforeEach, afterEach, it, describe */
var mockery = require('mockery')
var expect = require('chai').expect
//classic "drop somewhere"... yeah I'm a lazy guy
var formatBytes = function(bytes, precision) {
var kilobyte = 1024;
var megabyte = kilobyte * 1024;
var gigabyte = megabyte * 1024;
var terabyte = gigabyte * 1024;
// classic "drop somewhere"... yeah I'm a lazy guy
var formatBytes = function (bytes, precision) {
var kilobyte = 1024
var megabyte = kilobyte * 1024
var gigabyte = megabyte * 1024
var terabyte = gigabyte * 1024
if ((bytes >= 0) && (bytes < kilobyte)) {
return bytes + ' B ';
return bytes + ' B '
} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
return (bytes / kilobyte).toFixed(precision) + ' KB ';
return (bytes / kilobyte).toFixed(precision) + ' KB '
} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
return (bytes / megabyte).toFixed(precision) + ' MB ';
return (bytes / megabyte).toFixed(precision) + ' MB '
} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
return (bytes / gigabyte).toFixed(precision) + ' GB ';
return (bytes / gigabyte).toFixed(precision) + ' GB '
} else if (bytes >= terabyte) {
return (bytes / terabyte).toFixed(precision) + ' TB ';
return (bytes / terabyte).toFixed(precision) + ' TB '
} else {
return bytes + ' B ';
return bytes + ' B '
}
};
}
describe('pid usage', function() {
describe('pid usage', function () {
this.timeout(10000)
beforeEach(function() {
beforeEach(function () {
mockery.enable({

@@ -35,18 +35,34 @@ warnOnReplace: false,

useCleanCache: true
});
});
})
})
afterEach(function() {
mockery.deregisterAll();
mockery.disable();
});
afterEach(function () {
mockery.deregisterAll()
mockery.disable()
})
it('should get pid usage', function(cb) {
var pusage = require('../').stat;
pusage(process.pid, function(err, stat) {
it('should get pid usage', function (cb) {
var pusage = require('../').stat
pusage(process.pid, function (err, stat) {
expect(err).to.equal(null)
expect(stat).to.be.an('object')
expect(stat).to.have.property('cpu')
expect(stat).to.have.property('memory')
expect(err).to.be.null
console.log('Pcpu: %s', stat.cpu)
console.log('Mem: %s', formatBytes(stat.memory))
cb()
})
})
it('should get advanced pid usage', function (cb) {
var pusage = require('../').stat
pusage(process.pid, {advanced: true}, function (err, stat) {
expect(err).to.equal(null)
expect(stat).to.be.an('object')
expect(stat).to.have.property('cpu')
expect(stat).to.have.property('memory')
expect(stat).to.have.property('time')
expect(stat).to.have.property('start')

@@ -60,11 +76,10 @@ console.log('Pcpu: %s', stat.cpu)

it('should get pid usage multiple time', function(cb) {
var pusage = require('../').stat;
it('should get pid usage multiple time', function (cb) {
var pusage = require('../').stat
var num = 0
var interval
function launch() {
pusage(process.pid, function(err, stat) {
expect(err).to.be.null
function launch () {
pusage(process.pid, function (err, stat) {
expect(err).to.equal(null)
expect(stat).to.be.an('object')

@@ -81,3 +96,3 @@ expect(stat).to.have.property('cpu')

} else {
setTimeout(launch, 100);
setTimeout(launch, 100)
}

@@ -90,61 +105,63 @@ })

it('should calculate correct cpu when user space time is zero (kernel module)', function(cb) {
it('should calculate correct cpu when user space time is zero (kernel module)', function (cb) {
// force platform to linux to test this case
var os = require('os');
os.platform = function() {
return 'linux';
};
var os = require('os')
os.platform = function () {
return 'linux'
}
// override readFile to simulate the system time only (kernel module) case
var fs = require('fs');
var clock_tick = 100;
var fs = require('fs')
var clockTick = 100
fs.readFile = function(path, encoding, callback) {
if(path === '/proc/uptime') {
callback(null, '0 0');
fs.readFile = function (path, encoding, callback) {
if (path === '/proc/uptime') {
callback(null, '0 0')
} else { // proc/<pid>/stat
var infos = '0 (test)';
for(var i = 0; i < 22; i++) {
if(i === 12) {
infos += ' '+currentStime;
var infos = '0 (test)'
for (var i = 0; i < 22; i++) {
if (i === 12) {
infos += ' ' + currentStime
} else {
infos += ' 0';
infos += ' 0'
}
}
callback(null, infos);
callback(null, infos)
}
};
}
var helpers = require('../lib/helpers');
helpers.cpu = function(next) {
var helpers = require('../lib/helpers')
helpers.cpu = function (next) {
next(null, {
clock_tick: clock_tick,
uptime: clock_tick,
pagesize: 4096
})
clockTick: clockTick,
uptime: clockTick,
pagesize: 4096
})
}
// mock out to simulate kernel module and linux platform
mockery.registerMock('fs', fs);
mockery.registerMock('os', os);
mockery.registerMock('./helpers.js', helpers);
mockery.registerMock('fs', fs)
mockery.registerMock('os', os)
mockery.registerMock('./helpers.js', helpers)
var pusage = require('..');
var pusage = require('..')
// set the previous history as if kernel module usage had been called before
var kernel_module_pid = 0;
var currentStime = 10000*clock_tick;
var previousStime = 2000*clock_tick;
var kernelModulePid = 0
var currentStime = 10000 * clockTick
var previousStime = 2000 * clockTick
pusage._history[kernel_module_pid] = {};
pusage._history[kernel_module_pid].uptime = 0;
pusage._history[kernel_module_pid].utime = 0;
pusage._history[kernel_module_pid].stime = previousStime;
pusage._history[kernelModulePid] = {}
pusage._history[kernelModulePid].uptime = 0
pusage._history[kernelModulePid].utime = 0
pusage._history[kernelModulePid].stime = previousStime
pusage.stat(kernel_module_pid, function(err, stat) {
expect(stat.cpu).to.be.equal((currentStime - previousStime)/clock_tick);
cb();
});
});
pusage.stat(kernelModulePid, function (err, stat) {
if (err) {
return cb(err)
}
expect(stat.cpu).to.be.equal((currentStime - previousStime) / clockTick)
cb()
})
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc