Comparing version 0.0.6 to 0.0.7
44
index.js
@@ -7,25 +7,25 @@ var os = require('os') | ||
return function(pid, options, cb) { | ||
return function(pid, options, cb) { | ||
if(typeof options == 'function') { | ||
cb = options | ||
options = {} | ||
} | ||
if(typeof options == 'function') { | ||
cb = options | ||
options = {} | ||
} | ||
return stats[stat_type](pid, options, cb) | ||
} | ||
return stats[stat_type](pid, options, cb) | ||
} | ||
} | ||
var pusage = { | ||
darwin: wrapper('ps'), | ||
sunos: wrapper('ps'), | ||
freebsd: wrapper('ps'), | ||
win: wrapper('win'), | ||
linux: wrapper('proc'), | ||
aix: wrapper('ps'), | ||
unsupported: function(pid, options, cb) { | ||
cb = typeof options == 'function' ? options : cb | ||
darwin: wrapper('ps'), | ||
sunos: wrapper('ps'), | ||
freebsd: wrapper('ps'), | ||
win: wrapper('win'), | ||
linux: wrapper('proc'), | ||
aix: wrapper('ps'), | ||
unsupported: function(pid, options, cb) { | ||
cb = typeof options == 'function' ? options : cb | ||
cb(new Error(os.platform()+' is not supported yet, please fire an issue (https://github.com/soyuka/pidusage)')) | ||
} | ||
cb(new Error(os.platform()+' is not supported yet, please fire an issue (https://github.com/soyuka/pidusage)')) | ||
} | ||
} | ||
@@ -35,7 +35,7 @@ | ||
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' | ||
return pusage[platform].apply(stats, [].slice.call(arguments)) | ||
} | ||
return pusage[platform].apply(stats, [].slice.call(arguments)) | ||
} |
@@ -5,39 +5,39 @@ var os = require('os') | ||
module.exports = { | ||
getconf: function(keyword, options, next) { | ||
getconf: function(keyword, options, next) { | ||
if(typeof options == 'function') { | ||
done = options | ||
options = { default: '' } | ||
} | ||
if(typeof options == 'function') { | ||
done = options | ||
options = { default: '' } | ||
} | ||
exec('getconf '+keyword, function(error, stdout, stderr) { | ||
if(error !== null) { | ||
console.error('Error while getting '+keyword, error) | ||
return next(null, options.default) | ||
} | ||
exec('getconf '+keyword, function(error, stdout, stderr) { | ||
if(error !== null) { | ||
console.error('Error while getting '+keyword, error) | ||
return next(null, options.default) | ||
} | ||
stdout = parseInt(stdout) | ||
stdout = parseInt(stdout) | ||
if(!isNaN(stdout)) { | ||
return next(null, stdout) | ||
} | ||
if(!isNaN(stdout)) { | ||
return next(null, stdout) | ||
} | ||
return next(null, options.default) | ||
}) | ||
}, | ||
cpu: function(next) { | ||
var self = this | ||
return next(null, options.default) | ||
}) | ||
}, | ||
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, clock_tick) { | ||
self.getconf('PAGESIZE', {default: 4096}, function(err, pagesize) { | ||
next(null, { | ||
clock_tick: clock_tick, | ||
uptime: os.uptime(), | ||
pagesize: pagesize | ||
}) | ||
next(null, { | ||
clock_tick: clock_tick, | ||
uptime: os.uptime(), | ||
pagesize: pagesize | ||
}) | ||
}) | ||
}) | ||
} | ||
} | ||
}) | ||
}) | ||
} | ||
} |
234
lib/stats.js
@@ -8,141 +8,145 @@ var os = require('os') | ||
var stats = { | ||
history: {}, | ||
cpu: null, //used to store cpu informations | ||
proc: function(pid, options, done) { | ||
history: {}, | ||
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) { | ||
done(err, null) | ||
} | ||
self.cpu.uptime = uptime.split(' ')[0] | ||
self.proc_calc(pid, options, done) | ||
}) | ||
} else { | ||
helpers.cpu(function(err, cpu) { | ||
self.cpu = cpu | ||
self.proc_calc(pid, options, done) | ||
}) | ||
} | ||
}, | ||
proc_calc: function(pid, options, done) { | ||
var history = this.history[pid] ? this.history[pid] : {}, cpu = this.cpu | ||
, self = this | ||
if(this.cpu !== null) { | ||
fs.readFile('/proc/uptime', 'utf8', function(err, uptime) { | ||
if(err) { | ||
done(err, null) | ||
} else if(uptime === undefined) { | ||
console.error("We couldn't find uptime from /proc/uptime") | ||
self.cpu.uptime = os.uptime() | ||
} else { | ||
self.cpu.uptime = uptime.split(' ')[0] | ||
} | ||
// Arguments to path.join must be strings | ||
fs.readFile(p.join('/proc', ''+pid, 'stat'), 'utf8', function(err, infos) { | ||
return self.proc_calc(pid, options, done) | ||
}) | ||
} else { | ||
helpers.cpu(function(err, cpu) { | ||
self.cpu = cpu | ||
return self.proc_calc(pid, options, done) | ||
}) | ||
} | ||
}, | ||
proc_calc: function(pid, options, done) { | ||
var history = this.history[pid] ? this.history[pid] : {}, cpu = this.cpu | ||
, self = this | ||
if(err) | ||
return done(err, null) | ||
//Arguments to path.join must be strings | ||
fs.readFile(p.join('/proc', ''+pid, 'stat'), 'utf8', function(err, infos) { | ||
//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 | ||
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]) | ||
} | ||
if(err) | ||
return done(err, null) | ||
//http://stackoverflow.com/questions/16726779/total-cpu-usage-of-an-application-from-proc-pid-stat/16736599#16736599 | ||
//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(' ') | ||
var childrens = options.childrens ? stat.cutime + stat.cstime : 0, total | ||
//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]) | ||
} | ||
if(history.utime) { | ||
total = (stat.stime - history.stime) + (stat.utime - history.utime) + childrens | ||
} else { | ||
total = stat.stime + stat.utime + childrens | ||
} | ||
//http://stackoverflow.com/questions/16726779/total-cpu-usage-of-an-application-from-proc-pid-stat/16736599#16736599 | ||
total = total / cpu.clock_tick | ||
var childrens = options.childrens ? stat.cutime + stat.cstime : 0, total | ||
//time elapsed between calls | ||
var seconds = history.uptime !== undefined ? cpu.uptime - history.uptime : stat.start - cpu.uptime | ||
seconds = Math.abs(seconds) | ||
seconds = seconds === 0 ? 0.1 : seconds //we sure can't divide through 0 | ||
if(history.utime) { | ||
total = (stat.stime - history.stime) + (stat.utime - history.utime) + childrens | ||
} else { | ||
total = stat.stime + stat.utime + childrens | ||
} | ||
self.history[pid] = stat | ||
self.history[pid].seconds = seconds | ||
self.history[pid].uptime = cpu.uptime | ||
total = total / cpu.clock_tick | ||
return done(null, { | ||
cpu: (total / seconds) * 100, | ||
memory: stat.rss * cpu.pagesize | ||
}) | ||
}) | ||
}, | ||
/** | ||
* Get pid informations through ps command | ||
* @param {int} pid | ||
* @return {Function} done (err, stat) | ||
* on os x skip headers with pcpu=,rss= | ||
* on linux it could be --no-header | ||
* on solaris 11 can't figure out a way to do this properly so... | ||
*/ | ||
ps: function(pid, options, done) { | ||
//time elapsed between calls | ||
var seconds = history.uptime !== undefined ? cpu.uptime - history.uptime : stat.start - cpu.uptime | ||
seconds = Math.abs(seconds) | ||
seconds = seconds === 0 ? 0.1 : seconds //we sure can't divide through 0 | ||
var cmd = 'ps -o pcpu,rss -p ' | ||
self.history[pid] = stat | ||
self.history[pid].seconds = seconds | ||
self.history[pid].uptime = cpu.uptime | ||
if(os.platform() == 'aix') | ||
cmd = 'ps -o pcpu,rssize -p ' //this one could work on other platforms | ||
return done(null, { | ||
cpu: (total / seconds) * 100, | ||
memory: stat.rss * cpu.pagesize | ||
}) | ||
}) | ||
}, | ||
/** | ||
* Get pid informations through ps command | ||
* @param {int} pid | ||
* @return {Function} done (err, stat) | ||
* on os x skip headers with pcpu=,rss= | ||
* on linux it could be --no-header | ||
* on solaris 11 can't figure out a way to do this properly so... | ||
*/ | ||
ps: function(pid, options, done) { | ||
exec(cmd + pid, function(error, stdout, stderr) { | ||
if(error) { | ||
return done(error) | ||
} | ||
var cmd = 'ps -o pcpu,rss -p ' | ||
stdout = stdout.split(os.EOL)[1] | ||
stdout = stdout.replace(/^\s+/, '').replace(/\s\s+/g, ' ').split(' ') | ||
if(os.platform() == 'aix') | ||
cmd = 'ps -o pcpu,rssize -p ' //this one could work on other platforms | ||
return done(null, { | ||
cpu: parseFloat(stdout[0].replace(',', '.')), | ||
memory: parseFloat(stdout[1]) * 1024 | ||
}) | ||
}) | ||
}, | ||
/** | ||
* This is really in a beta stage | ||
*/ | ||
win: function(pid, options, done) { | ||
exec(cmd + pid, function(error, stdout, stderr) { | ||
if(error) { | ||
return done(error) | ||
} | ||
// var history = this.history[pid] ? this.history[pid] : {} | ||
// , uptime = os.uptime() | ||
// , self = this | ||
stdout = stdout.split(os.EOL)[1] | ||
stdout = stdout.replace(/^\s+/, '').replace(/\s\s+/g, ' ').split(' ') | ||
//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 | ||
exec('wmic PROCESS '+pid+' get workingsetsize,usermodetime,kernelmodetime', function(error, stdout, stderr) { | ||
if(error) { | ||
console.log(error) | ||
return done(error) | ||
} | ||
return done(null, { | ||
cpu: parseFloat(stdout[0].replace(',', '.')), | ||
memory: parseFloat(stdout[1]) * 1024 | ||
}) | ||
}) | ||
}, | ||
/** | ||
* This is really in a beta stage | ||
*/ | ||
win: function(pid, options, done) { | ||
stdout = stdout.split(os.EOL)[1] | ||
stdout = stdout.replace(/\s\s+/g, ' ').split(' ') | ||
// var history = this.history[pid] ? this.history[pid] : {} | ||
// , uptime = os.uptime() | ||
// , self = this | ||
var stats = { | ||
kernelmodetime: parseFloat(stdout[0]), | ||
usermodetime: parseFloat(stdout[1]), | ||
workingsetsize: parseFloat(stdout[2]) | ||
} | ||
//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 | ||
exec('wmic PROCESS '+pid+' get workingsetsize,usermodetime,kernelmodetime', function(error, stdout, stderr) { | ||
if(error) { | ||
console.log(error) | ||
return done(error) | ||
} | ||
//according to http://technet.microsoft.com/en-us/library/ee176718.aspx | ||
var total = (stats.usermodetime + stats.kernelmodetime) / 10000000 //seconds | ||
stdout = stdout.split(os.EOL)[1] | ||
stdout = stdout.replace(/\s\s+/g, ' ').split(' ') | ||
return done(null, { | ||
cpu: total, | ||
memory: stats.workingsetsize | ||
}) | ||
}) | ||
} | ||
var stats = { | ||
kernelmodetime: parseFloat(stdout[0]), | ||
usermodetime: parseFloat(stdout[1]), | ||
workingsetsize: parseFloat(stdout[2]) | ||
} | ||
//according to http://technet.microsoft.com/en-us/library/ee176718.aspx | ||
var total = (stats.usermodetime + stats.kernelmodetime) / 10000000 //seconds | ||
return done(null, { | ||
cpu: total, | ||
memory: stats.workingsetsize | ||
}) | ||
}) | ||
} | ||
} | ||
module.exports = stats; | ||
module.exports = stats; |
{ | ||
"name": "pidusage", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "Process cpu % and memory use of a PID", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -9,6 +9,6 @@ var http = require('http'), pusage = require('../') | ||
var interval = setInterval(function () { | ||
console.log('\033[2J') | ||
pusage(process.pid, function(err, stat) { | ||
console.log(stat) | ||
}) | ||
console.log('\033[2J') | ||
pusage(process.pid, function(err, stat) { | ||
console.log(stat) | ||
}) | ||
}, 100) | ||
@@ -18,2 +18,2 @@ | ||
clearInterval(interval) | ||
}) | ||
}) |
@@ -6,3 +6,3 @@ var pusage = require('../') | ||
//classic "drop somewhere"... yeah I'm a lazy guy | ||
//classic "drop somewhere"... yeah I'm a lazy guy | ||
var formatBytes = function(bytes, precision) { | ||
@@ -33,53 +33,53 @@ var kilobyte = 1024 | ||
console.log('\033[2J') | ||
console.log('\033[2J') | ||
var j = 500, arr = [] | ||
var j = 500, arr = [] | ||
while(j--) { | ||
arr[j] = [] | ||
for (var k = 0; k < 1000; k++) { | ||
arr[j][k] = {lorem: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non odio venenatis, pretium ligula nec, fringilla ipsum. Sed a erat et sem blandit dignissim. Pellentesque sollicitudin felis eu mattis porta. Nullam nec nibh nisl. Phasellus convallis vulputate massa vitae fringilla. Etiam facilisis lectus in odio lacinia rutrum. Praesent facilisis vitae urna a suscipit. Aenean lacinia blandit lorem, et ullamcorper metus sagittis faucibus. Nam porta eros nisi, at adipiscing quam varius eu. Vivamus sed sem quis lorem varius posuere ut quis elit.'} | ||
} | ||
} | ||
big_memory_leak.push(arr) | ||
while(j--) { | ||
arr[j] = [] | ||
pusage(process.pid, function(err, stat) { | ||
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(true) | ||
else if(stat.memory > 209715200) { | ||
console.log("That's enough right?") | ||
cb(true) | ||
} | ||
for (var k = 0; k < 1000; k++) { | ||
arr[j][k] = {lorem: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non odio venenatis, pretium ligula nec, fringilla ipsum. Sed a erat et sem blandit dignissim. Pellentesque sollicitudin felis eu mattis porta. Nullam nec nibh nisl. Phasellus convallis vulputate massa vitae fringilla. Etiam facilisis lectus in odio lacinia rutrum. Praesent facilisis vitae urna a suscipit. Aenean lacinia blandit lorem, et ullamcorper metus sagittis faucibus. Nam porta eros nisi, at adipiscing quam varius eu. Vivamus sed sem quis lorem varius posuere ut quis elit.'} | ||
} | ||
} | ||
i++ | ||
return cb(false) | ||
// }) | ||
}) | ||
big_memory_leak.push(arr) | ||
pusage(process.pid, function(err, stat) { | ||
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(true) | ||
else if(stat.memory > 209715200) { | ||
console.log("That's enough right?") | ||
cb(true) | ||
} | ||
i++ | ||
return cb(false) | ||
// }) | ||
}) | ||
} | ||
var interval = function() { | ||
return setTimeout(function() { | ||
return setTimeout(function() { | ||
stress(function(stop) { | ||
if(stop) | ||
process.exit() | ||
else | ||
return interval() | ||
}) | ||
stress(function(stop) { | ||
if(stop) | ||
process.exit() | ||
else | ||
return interval() | ||
}) | ||
}, 400) | ||
}, 400) | ||
} | ||
setTimeout(function() { | ||
interval() | ||
interval() | ||
}, 2000) |
var pusage = require('../') | ||
, expect = require('chai').expect | ||
//classic "drop somewhere"... yeah I'm a lazy guy | ||
//classic "drop somewhere"... yeah I'm a lazy guy | ||
var formatBytes = function(bytes, precision) { | ||
@@ -27,35 +27,35 @@ var kilobyte = 1024; | ||
describe('pid usage', function() { | ||
this.timeout(4000) | ||
this.timeout(4000) | ||
it('should get pid usage', function(cb) { | ||
pusage(process.pid, function(err, stat) { | ||
it('should get pid usage', function(cb) { | ||
pusage(process.pid, function(err, stat) { | ||
expect(err).to.be.null | ||
expect(stat).to.be.an('object') | ||
expect(stat).to.have.property('cpu') | ||
expect(stat).to.have.property('memory') | ||
expect(err).to.be.null | ||
expect(stat).to.be.an('object') | ||
expect(stat).to.have.property('cpu') | ||
expect(stat).to.have.property('memory') | ||
console.log('Pcpu: %s', stat.cpu) | ||
console.log('Mem: %s', formatBytes(stat.memory)) | ||
console.log('Pcpu: %s', stat.cpu) | ||
console.log('Mem: %s', formatBytes(stat.memory)) | ||
cb() | ||
}) | ||
}) | ||
cb() | ||
}) | ||
}) | ||
it('should get pid usage again', function(cb) { | ||
setTimeout(function() { | ||
pusage(process.pid, function(err, stat) { | ||
it('should get pid usage again', function(cb) { | ||
setTimeout(function() { | ||
pusage(process.pid, function(err, stat) { | ||
expect(err).to.be.null | ||
expect(stat).to.be.an('object') | ||
expect(stat).to.have.property('cpu') | ||
expect(stat).to.have.property('memory') | ||
expect(err).to.be.null | ||
expect(stat).to.be.an('object') | ||
expect(stat).to.have.property('cpu') | ||
expect(stat).to.have.property('memory') | ||
console.log('Pcpu: %s', stat.cpu) | ||
console.log('Mem: %s', formatBytes(stat.memory)) | ||
console.log('Pcpu: %s', stat.cpu) | ||
console.log('Mem: %s', formatBytes(stat.memory)) | ||
cb() | ||
}) | ||
}, 2000) | ||
}) | ||
cb() | ||
}) | ||
}, 2000) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16722
316