project files added

This commit is contained in:
mhalfmann
2021-06-15 16:00:08 +02:00
parent e156e2f053
commit db46afa351
13928 changed files with 1569902 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
### 2.0
- allow multiple pids
- remove `advanced` option
- don't use `/proc` files anymore but use `ps` instead
- more tests
- API change no more `stat` method, module exports a single function
- no more `unmonitor` method, this is handed internally
- the default call now returns more data:
```
{
cpu: 10.0, // percentage (it may happen to be greater than 100%)
memory: 357306368, // bytes
ppid: 312, // PPID
pid: 727, // PID
ctime: 867000, // ms user + system time
elapsed: 6650000, // ms since the start of the process
timestamp: 864000000 // ms since epoch
}
```
### 1.2.0
Introduce `advanced` option to get time, and start
### 1.1.0
Windows: (wmic) goes back to the first version of wmic, naming `wmic process {pid} get workingsetsize,usermodetime,kernelmodetime`. CPU usage % is computed on the flight, per pid.
### 1.0.5
Windows: (wmic) Use raw data instead of formatted this should speed up wmic
### 0.1.0
API changes:
```
require('pidusage').stat(pid, fn)
```
instead of:
```
require('pidusage')(pid, fn)
```
Adds a `unmonitor` method to clear process history
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 soyuka
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+137
View File
@@ -0,0 +1,137 @@
# pidusage
[![Mac/Linux Build Status](https://img.shields.io/travis/soyuka/pidusage/master.svg?label=MacOS%20%26%20Linux)](https://travis-ci.org/soyuka/pidusage)
[![Windows Build status](https://img.shields.io/appveyor/ci/soyuka/pidusage/master.svg?label=Windows)](https://ci.appveyor.com/project/soyuka/pidusage)
[![Code coverage](https://img.shields.io/codecov/c/github/soyuka/pidusage/master.svg)](https://codecov.io/gh/soyuka/pidusage)
[![npm version](https://img.shields.io/npm/v/pidusage.svg)](https://www.npmjs.com/package/pidusage)
[![license](https://img.shields.io/github/license/soyuka/pidusage.svg)](https://github.com/soyuka/pidusage/tree/master/license)
Cross-platform process cpu % and memory usage of a PID.
## Synopsis
Ideas from https://github.com/arunoda/node-usage but with no C-bindings.
Please note that if you need to check a Node.JS script process cpu and memory usage, you can use [`process.cpuUsage`][node:cpuUsage] and [`process.memoryUsage`][node:memUsage] since node v6.1.0. This script remain useful when you have no control over the remote script, or if the process is not a Node.JS process.
## Usage
```js
var pidusage = require('pidusage')
// Compute statistics every second:
setInterval(function () {
pidusage(process.pid, function (err, stats) {
console.log(stats)
// => {
// cpu: 10.0, // percentage (from 0 to 100*vcore)
// memory: 357306368, // bytes
// ppid: 312, // PPID
// pid: 727, // PID
// ctime: 867000, // ms user + system time
// elapsed: 6650000, // ms since the start of the process
// timestamp: 864000000 // ms since epoch
// }
})
}, 1000)
// It supports also multiple pids
pidusage([727, 1234], function (err, stats) {
console.log(stats)
// => {
// 727: {
// cpu: 10.0, // percentage (from 0 to 100*vcore)
// memory: 357306368, // bytes
// ppid: 312, // PPID
// pid: 727, // PID
// ctime: 867000, // ms user + system time
// elapsed: 6650000, // ms since the start of the process
// timestamp: 864000000 // ms since epoch
// },
// 1234: {
// cpu: 0.1, // percentage (from 0 to 100*vcore)
// memory: 3846144, // bytes
// ppid: 727, // PPID
// pid: 1234, // PID
// ctime: 0, // ms user + system time
// elapsed: 20000, // ms since the start of the process
// timestamp: 864000000 // ms since epoch
// }
// }
})
// If no callback is given it returns a promise instead
const stats = await pidusage(process.pid)
console.log(stats)
// => {
// cpu: 10.0, // percentage (from 0 to 100*vcore)
// memory: 357306368, // bytes
// ppid: 312, // PPID
// pid: 727, // PID
// ctime: 867000, // ms user + system time
// elapsed: 6650000, // ms since the start of the process
// timestamp: 864000000 // ms since epoch
// }
```
## Compatibility
| Property | Linux | FreeBSD | NetBSD | SunOS | macOS | Win | AIX | Alpine
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `cpu` | ✅ | ❓ | ❓ | ❓ | ✅ | ️ | ❓ | ✅ |
| `memory` | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |
| `pid` | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |
| `ctime` | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |
| `elapsed` | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |
| `timestamp` | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |
✅ = Working
️ = Not Accurate
❓ = Should Work
❌ = Not Working
Please if your platform is not supported or if you have reported wrong readings
[file an issue][new issue].
## API
<a name="pidusage"></a>
### pidusage(pids, [options = {}], [callback]) ⇒ <code>[Promise.&lt;Object&gt;]</code>
Get pid informations.
**Kind**: global function
**Returns**: <code>Promise.&lt;Object&gt;</code> - Only when the callback is not provided.
**Access**: public
| Param | Type | Description |
| --- | --- | --- |
| pids | <code>Number</code> \| <code>Array.&lt;Number&gt;</code> \| <code>String</code> \| <code>Array.&lt;String&gt;</code> | A pid or a list of pids. |
| [callback] | <code>function</code> | Called when the statistics are ready. If not provided a promise is returned instead. |
## Related
- [pidusage-tree][gh:pidusage-tree] -
Compute a pidusage tree
## Authors
- **Antoine Bluchet** - [soyuka][github:soyuka]
- **Simone Primarosa** - [simonepri][github:simonepri]
See also the list of [contributors][contributors] who participated in this project.
## License
This project is licensed under the MIT License - see the [LICENSE][license] file for details.
<!-- Links -->
[new issue]: https://github.com/soyuka/pidusage/issues/new
[license]: https://github.com/soyuka/pidusage/tree/master/LICENSE
[contributors]: https://github.com/soyuka/pidusage/contributors
[github:soyuka]: https://github.com/soyuka
[github:simonepri]: https://github.com/simonepri
[gh:pidusage-tree]: https://github.com/soyuka/pidusage-tree
[node:cpuUsage]: https://nodejs.org/api/process.html#process_process_cpuusage_previousvalue
[node:memUsage]: https://nodejs.org/api/process.html#process_process_memoryusage
+37
View File
@@ -0,0 +1,37 @@
'use strict'
var stats = require('./lib/stats')
/**
* Get pid informations.
* @public
* @param {Number|Number[]|String|String[]} pids A pid or a list of pids.
* @param {Object} [options={}] Options object
* @param {Function} [callback=undefined] Called when the statistics are ready.
* If not provided a promise is returned instead.
* @returns {Promise.<Object>} Only when the callback is not provided.
*/
function pidusage (pids, options, callback) {
if (typeof options === 'function') {
callback = options
options = {}
}
if (options === undefined) {
options = {}
}
if (typeof callback === 'function') {
stats(pids, options, callback)
return
}
return new Promise(function (resolve, reject) {
stats(pids, options, function (err, data) {
if (err) return reject(err)
resolve(data)
})
})
}
module.exports = pidusage
+48
View File
@@ -0,0 +1,48 @@
'use strict'
var spawn = require('child_process').spawn
/**
* Spawn a binary and read its stdout.
* @param {String} cmd
* @param {String[]} args
* @param {Function} done(err, stdout)
*/
function run (cmd, args, options, done) {
if (typeof options === 'function') {
done = options
options = undefined
}
var executed = false
var ch = spawn(cmd, args, options)
var stdout = ''
var stderr = ''
ch.stdout.on('data', function (d) {
stdout += d.toString()
})
ch.stderr.on('data', function (d) {
stderr += d.toString()
})
ch.on('error', function (err) {
if (executed) return
executed = true
done(new Error(err))
})
ch.on('close', function (code, signal) {
if (executed) return
executed = true
if (stderr) {
return done(new Error(stderr))
}
done(null, stdout, code)
})
}
module.exports = run
+87
View File
@@ -0,0 +1,87 @@
var os = require('os')
var fs = require('fs')
var exec = require('child_process').exec
var parallel = require('./parallel')
/**
* Gathers Clock, PageSize and system uptime through /proc/uptime
* This method is mocked in procfile tests
*/
function updateCpu (cpu, next) {
if (cpu !== null) {
getRealUptime(function (err, uptime) {
if (err) return next(err)
cpu.uptime = uptime
next(null, cpu)
})
return
}
parallel([
getClockAndPageSize,
getRealUptime
], function (err, data) {
if (err) return next(err)
cpu = {
clockTick: data[0].clockTick,
pageSize: data[0].pageSize,
uptime: data[1]
}
next(null, cpu)
})
}
module.exports = updateCpu
/**
* Fallback on os.uptime(), though /proc/uptime is more precise
*/
function getRealUptime (next) {
fs.readFile('/proc/uptime', 'utf8', function (err, uptime) {
if (err || uptime === undefined) {
console.warn("[pidusage] We couldn't find uptime from /proc/uptime, using os.uptime() value")
return next(null, os.uptime())
}
return next(null, parseFloat(uptime.split(' ')[0]))
})
}
function getClockAndPageSize (next) {
parallel([
function getClockTick (cb) {
getconf('CLK_TCK', {default: 100}, cb)
},
function getPageSize (cb) {
getconf('PAGESIZE', {default: 4096}, cb)
}
], function (err, data) {
if (err) return next(err)
next(null, {clockTick: data[0], pageSize: data[1]})
})
}
function getconf (keyword, options, next) {
if (typeof options === 'function') {
next = 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)
}
stdout = parseInt(stdout)
if (!isNaN(stdout)) {
return next(null, stdout)
}
return next(null, options.default)
})
}
+44
View File
@@ -0,0 +1,44 @@
// execute an array of asynchronous functions in parallel
// @param {Array} fns - an array of functions
// @param {Function} done - callback(err, results)
function parallel (fns, options, done) {
if (typeof options === 'function') {
done = options
options = {}
}
var keys
if (!Array.isArray(fns)) { keys = Object.keys(fns) }
var length = keys ? keys.length : fns.length
var pending = length
var results = keys ? {} : []
function each (i, err, result) {
results[i] = result
if (--pending === 0 || (err && !options.graceful)) {
if (options.graceful && err && length > 1) {
err = null
}
done && done(err, results)
done = null
}
}
if (keys) {
keys.forEach(function (key) {
fns[key](function (err, res) {
each(key, err, res)
})
})
} else {
fns.forEach(function (fn, i) {
fn(function (err, res) {
each(i, err, res)
})
})
}
}
module.exports = parallel
+75
View File
@@ -0,0 +1,75 @@
'use strict'
var DEFAULT_MAXAGE = 60000
var expiration = {}
var history = {}
var expireListeners = {}
var size = 0
var interval = null
function get (pid, maxage) {
if (maxage <= 0) {
return
}
if (history[pid] !== undefined) {
expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)
}
return history[pid]
}
function set (pid, object, maxage, onExpire) {
if (object === undefined || maxage <= 0) return
expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)
if (history[pid] === undefined) {
size++
sheduleInvalidator(maxage)
}
history[pid] = object
if (onExpire) {
expireListeners[pid] = onExpire
}
}
function sheduleInvalidator (maxage) {
if (size > 0) {
if (interval === null) {
interval = setInterval(runInvalidator, (maxage || DEFAULT_MAXAGE) / 2)
}
return
}
if (interval !== null) {
clearInterval(interval)
interval = null
}
}
function runInvalidator () {
var now = Date.now()
var pids = Object.keys(expiration)
for (var i = 0; i < pids.length; i++) {
var pid = pids[i]
if (expiration[pid] < now) {
size--
if (expireListeners[pid]) {
expireListeners[pid](history[pid])
}
delete history[pid]
delete expiration[pid]
delete expireListeners[pid]
}
}
sheduleInvalidator()
}
module.exports = {
get: get,
set: set
}
+141
View File
@@ -0,0 +1,141 @@
var fs = require('fs')
var path = require('path')
var updateCpu = require('./helpers/cpu')
var parallel = require('./helpers/parallel')
var history = require('./history')
var cpuInfo = null
var Buffer = require('safe-buffer').Buffer
var SIZE = 1024 // if the stat file is bigger then this I'll buy you a drink
function noop () {}
function open (path, history, cb) {
if (history.fd) { return cb(null, history.fd) }
fs.open(path, 'r', cb)
}
function close (history) {
if (history.fd) {
fs.close(history.fd, noop)
}
}
function readUntilEnd (fd, buf, cb) {
var firstRead = false
if (typeof buf === 'function') {
cb = buf
buf = Buffer.alloc(SIZE)
firstRead = true
}
fs.read(fd, buf, 0, SIZE, 0, function (err, bytesRead, buffer) {
if (err) {
cb(err)
return
}
var data = Buffer.concat([buf, buffer], firstRead ? bytesRead : buf.length + bytesRead)
if (bytesRead === SIZE) {
readUntilEnd(fd, data, cb)
return
}
cb(null, buf)
})
}
function readProcFile (pid, options, done) {
var hst = history.get(pid, options.maxage)
var again = false
if (hst === undefined) {
again = true
hst = {}
}
// Arguments to path.join must be strings
open(path.join('/proc', '' + pid, 'stat'), hst, function (err, fd) {
if (err) {
if (err.code === 'ENOENT') {
err.message = 'No maching pid found'
}
return done(err, null)
}
if (err) {
return done(err)
}
readUntilEnd(fd, function (err, buffer) {
if (err) {
return done(err)
}
var infos = buffer.toString('utf8')
var date = Date.now()
// 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 = {
ppid: parseInt(infos[1]),
utime: parseFloat(infos[11]),
stime: parseFloat(infos[12]),
cutime: parseFloat(infos[13]),
cstime: parseFloat(infos[14]),
start: parseFloat(infos[19]) / cpuInfo.clockTick,
rss: parseFloat(infos[21]),
uptime: cpuInfo.uptime,
fd: fd
}
var memory = stat.rss * cpuInfo.pageSize
// https://stackoverflow.com/a/16736599/3921589
var childrens = options.childrens ? stat.cutime + stat.cstime : 0
// process usage since last call in seconds
var total = (stat.stime - (hst.stime || 0) + stat.utime - (hst.utime || 0) + childrens) / cpuInfo.clockTick
// time elapsed between calls in seconds
var seconds = Math.abs(hst.uptime !== undefined ? stat.uptime - hst.uptime : stat.start - stat.uptime)
var cpu = seconds > 0 ? (total / seconds) * 100 : 0
history.set(pid, stat, options.maxage, close)
if (again) {
return readProcFile(pid, options, done)
}
return done(null, {
cpu: cpu,
memory: memory,
ctime: (stat.utime + stat.stime) / cpuInfo.clockTick,
elapsed: date - (stat.start * 1000),
timestamp: stat.start * 1000, // start date
pid: pid,
ppid: stat.ppid
})
})
})
}
function procfile (pids, options, done) {
updateCpu(cpuInfo, function (err, result) {
if (err) return done(err)
cpuInfo = result
var fns = {}
pids.forEach(function (pid, i) {
fns[pid] = function (cb) {
readProcFile(pid, options, cb)
}
})
parallel(fns, {graceful: true}, done)
})
}
module.exports = procfile
+126
View File
@@ -0,0 +1,126 @@
'use strict'
var os = require('os')
var bin = require('./bin')
var history = require('./history')
var PLATFORM = os.platform()
function parseTime (timestr, centisec) {
var time = 0
var tpart = timestr.split(/-|:|\./)
var i = tpart.length - 1
if (i >= 0 && centisec && PLATFORM === 'darwin') {
time += parseInt(tpart[i--], 10) * 10
}
if (i >= 0) { // Seconds
time += parseInt(tpart[i--], 10) * 1000
}
if (i >= 0) { // Minutes
time += parseInt(tpart[i--], 10) * 60000
}
if (i >= 0) { // Hours
time += parseInt(tpart[i--], 10) * 3600000
}
if (i >= 0) { // Days
time += parseInt(tpart[i--], 10) * 86400000
}
return time
}
/**
* Get pid informations through ps command.
* @param {Number[]} pids
* @param {Object} options
* @param {Function} done(err, stat)
*/
function ps (pids, options, done) {
var pArg = pids.join(',')
var args = ['-o', 'etime,pid,ppid,pcpu,rss,time', '-p', pArg]
if (PLATFORM === 'aix') {
args = ['-o', 'etime,pid,ppid,pcpu,rssize,time', '-p', pArg]
}
bin('ps', args, function (err, stdout, code) {
if (err) return done(err)
if (code === 1) {
return done(new Error('No maching pid found'))
}
if (code !== 0) {
return done(new Error('pidusage ps command exited with code ' + code))
}
var date = Date.now()
// Example of stdout on *nix.
// ELAPSED: format is [[dd-]hh:]mm:ss
// RSS: is counted as blocks of 1024 bytes
// TIME: format is [[dd-]hh:]mm:ss
// %CPU: goes from 0 to vcore * 100
//
// Refs: http://www.manpages.info/linux/ps.1.html
// NB: The columns are returned in the order given inside the -o option
//
// ELAPSED PID PPID %CPU RSS TIME
// 2-40:50:53 430 1 3.0 5145 1-02:03:04
// 40:50:53 432 430 0.0 2364 1-01:02:03
// 01:50:50 727 1 10.0 348932 14:27
// 00:20 7166 1 0.1 3756 0:00
// Example of stdout on Darwin
// ELAPSED: format is [[dd-]hh:]mm:ss
// RSS: is counted as blocks of 1024 bytes
// TIME: format is [[dd-]hh:]mm:ss.cc (cc are centiseconds)
// %CPU: goes from 0 to vcore * 100
//
// Refs: https://ss64.com/osx/ps.html
// NB: The columns are returned in the order given inside the -o option
//
// ELAPSED PID PPID %CPU RSS TIME
// 2-40:50:53 430 1 3.0 5145 1-02:03:04.07
// 40:50:53 432 430 0.0 2364 1-01:02:03.10
// 01:50:50 727 1 10.0 348932 14:27.26
// 00:20 7166 1 0.1 3756 0:00.02
stdout = stdout.split(os.EOL)
var statistics = {}
for (var i = 1; i < stdout.length; i++) {
var line = stdout[i].trim().split(/\s+/)
if (!line || line.length !== 6) {
continue
}
var pid = parseInt(line[1], 10)
var hst = history.get(pid, options.maxage)
if (hst === undefined) hst = {}
var ppid = parseInt(line[2], 10)
var memory = parseInt(line[4], 10) * 1024
var etime = parseTime(line[0])
var ctime = parseTime(line[5], true)
var total = (ctime - (hst.ctime || 0))
// time elapsed between calls in seconds
var seconds = Math.abs(hst.elapsed !== undefined ? etime - hst.elapsed : etime)
var cpu = seconds > 0 ? (total / seconds) * 100 : 0
statistics[pid] = {
cpu: cpu,
memory: memory,
ppid: ppid,
pid: pid,
ctime: ctime,
elapsed: etime,
timestamp: date
}
history.set(pid, statistics[pid], options.maxage)
}
done(null, statistics)
})
}
module.exports = ps
+86
View File
@@ -0,0 +1,86 @@
'use strict'
var fs = require('fs')
var os = require('os')
var platformToMethod = {
aix: 'ps',
alpine: 'procfile',
darwin: 'ps',
freebsd: 'ps',
linux: 'procfile',
netbsd: 'procfile',
sunos: 'ps',
win: 'wmic'
}
var ps = require('./ps')
var platform = os.platform()
if (fs.existsSync('/etc/alpine-release')) {
platform = 'alpine'
}
if (platform.match(/^win/)) {
platform = 'win'
}
var stat
try {
stat = require('./' + platformToMethod[platform])
} catch (err) {}
/**
* @callback pidCallback
* @param {Error} err A possible error.
* @param {Object} statistics The object containing the statistics.
*/
/**
* Get pid informations.
* @public
* @param {Number|Number[]|String|String[]} pids A pid or a list of pids.
* @param {Object} [options={}] Options object
* @param {pidCallback} callback Called when the statistics are ready.
*/
function get (pids, options, callback) {
var fn = stat
if (platform !== 'win' && options.usePs === true) {
fn = ps
}
if (stat === undefined) {
return callback(new Error(os.platform() + ' is not supported yet, please open an issue (https://github.com/soyuka/pidusage)'))
}
var single = false
if (!Array.isArray(pids)) {
single = true
pids = [pids]
}
if (pids.length === 0) {
return callback(new TypeError('You must provide at least one pid'))
}
for (var i = 0; i < pids.length; i++) {
pids[i] = parseInt(pids[i], 10)
if (isNaN(pids[i]) || pids[i] < 0) {
return callback(new TypeError('One of the pids provided is invalid'))
}
}
fn(pids, options, function (err, stats) {
if (err) {
return callback(err)
}
if (single) {
callback(null, stats[pids[0]])
} else {
callback(null, stats)
}
})
}
module.exports = get
+130
View File
@@ -0,0 +1,130 @@
'use strict'
var os = require('os')
var bin = require('./bin')
var history = require('./history')
function parseDate (datestr) {
var year = datestr.substring(0, 4)
var month = datestr.substring(4, 6)
var day = datestr.substring(6, 8)
var hour = datestr.substring(8, 10)
var minutes = datestr.substring(10, 12)
var seconds = datestr.substring(12, 14)
var useconds = datestr.substring(15, 21)
var sign = datestr.substring(21, 22)
var tmz = parseInt(datestr.substring(22, 25), 10)
var tmzh = Math.floor(tmz / 60)
var tmzm = tmz % 60
return new Date(
year + '-' + month + '-' + day + 'T' + hour +
':' + minutes + ':' + seconds +
'.' + useconds +
sign + (tmzh > 9 ? tmzh : '0' + tmzh) + '' + (tmzm > 9 ? tmzm : '0' + tmzm)
)
}
/**
* Get pid informations through wmic command.
* @param {Number[]} pids
* @param {Object} options
* @param {Function} done(err, stat)
*/
function wmic (pids, options, done) {
var whereClause = 'ProcessId=' + pids[0]
for (var i = 1; i < pids.length; i++) {
whereClause += ' or ' + 'ProcessId=' + pids[i]
}
var args = [
'PROCESS',
'where',
'"' + whereClause + '"',
'get',
'CreationDate,KernelModeTime,ParentProcessId,ProcessId,UserModeTime,WorkingSetSize'
]
bin('wmic', args, {windowsHide: true, windowsVerbatimArguments: true}, function (err, stdout, code) {
if (err) {
if (err.message.indexOf('No Instance(s) Available.') !== -1) {
return done(new Error('No maching pid found'))
}
return done(err)
}
if (code !== 0) {
return done(new Error('pidusage wmic command exited with code ' + code))
}
var date = Date.now()
// Note: On Windows the returned value includes fractions of a second.
// Use Math.floor() to get whole seconds.
var uptime = Math.floor(os.uptime())
// Example of stdout on Windows 10
// CreationDate: is in the format yyyymmddHHMMSS.mmmmmmsUUU
// KernelModeTime: is in units of 100 ns
// UserModeTime: is in units of 100 ns
// WorkingSetSize: is in bytes
//
// Refs: https://superuser.com/a/937401/470946
// Refs: https://msdn.microsoft.com/en-us/library/aa394372(v=vs.85).aspx
// NB: The columns are returned in lexicographical order
//
// CreationDate KernelModeTime ParentProcessId ProcessId UserModeTime WorkingSetSize
// 20150329221650.080654+060 153750000 0 777 8556250000 110821376
stdout = stdout.split(os.EOL)
var again = false
var statistics = {}
for (var i = 1; i < stdout.length; i++) {
var line = stdout[i].trim().split(/\s+/)
if (!line || line.length !== 6) {
continue
}
var creation = parseDate(line[0])
var ppid = parseInt(line[2], 10)
var pid = parseInt(line[3], 10)
var kerneltime = Math.round(parseInt(line[1], 10) / 10000)
var usertime = Math.round(parseInt(line[4], 10) / 10000)
var memory = parseInt(line[5], 10)
var hst = history.get(pid, options.maxage)
if (hst === undefined) {
again = true
hst = {ctime: kerneltime + usertime, uptime: uptime}
}
// process usage since last call
var total = (kerneltime + usertime - hst.ctime) / 1000
// time elapsed between calls in seconds
var seconds = uptime - hst.uptime
var cpu = seconds > 0 ? (total / seconds) * 100 : 0
history.set(pid, {ctime: usertime + kerneltime, uptime: uptime}, options.maxage)
statistics[pid] = {
cpu: cpu,
memory: memory,
ppid: ppid,
pid: pid,
ctime: usertime + kerneltime,
elapsed: date - creation.getTime(),
timestamp: date
}
}
if (again) {
return wmic(pids, options, function (err, stats) {
if (err) return done(err)
done(null, Object.assign(statistics, stats))
})
}
done(null, statistics)
})
}
module.exports = wmic
+99
View File
@@ -0,0 +1,99 @@
{
"_args": [
[
"pidusage@2.0.16",
"C:\\Daten\\Git\\Tumortisch"
]
],
"_from": "pidusage@2.0.16",
"_id": "pidusage@2.0.16",
"_inBundle": false,
"_integrity": "sha512-9dhSBxpGvvpyycCukU8CqTqJ+YT8aVZ/AI1/hGWhU5nAAOs0zYBYMyIYBU/grKeCYuTS26TVllIRvf5vAfsgvw==",
"_location": "/pidusage",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "pidusage@2.0.16",
"name": "pidusage",
"escapedName": "pidusage",
"rawSpec": "2.0.16",
"saveSpec": null,
"fetchSpec": "2.0.16"
},
"_requiredBy": [
"/electron-process-reporter"
],
"_resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.16.tgz",
"_spec": "2.0.16",
"_where": "C:\\Daten\\Git\\Tumortisch",
"author": {
"name": "soyuka"
},
"ava": {
"verbose": true
},
"bugs": {
"url": "https://github.com/soyuka/pidusage/issues"
},
"contributors": [
{
"name": "Simone Primarosa",
"email": "simonepri@outlook.com",
"url": "https://simoneprimarosa.com"
}
],
"dependencies": {
"safe-buffer": "^5.1.2"
},
"description": "Cross-platform process cpu % and memory usage of a PID",
"devDependencies": {
"ava": "*",
"codecov": "^3.0.2",
"mockdate": "^2.0.2",
"mockery": "2.1.0",
"nyc": "^13.0.0",
"pify": "^3.0.0",
"standard": "*",
"string-to-stream": "^1.1.0",
"through": "^2.3.8",
"time-span": "^2.0.0"
},
"engines": {
"node": ">=4"
},
"files": [
"lib",
"index.js"
],
"homepage": "https://github.com/soyuka/pidusage",
"keywords": [
"pid",
"usage",
"ps",
"cpu",
"memory",
"proc"
],
"license": "MIT",
"main": "index.js",
"name": "pidusage",
"nyc": {
"reporter": [
"lcovonly",
"text"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/soyuka/pidusage.git"
},
"scripts": {
"alpine": "docker run -v $(pwd):/var/pidusage pidusage:latest npm test",
"bench": "ava -m \"*benchmark*\"",
"coverage": "codecov",
"lint": "standard",
"test": "standard && nyc ava -m \"!*benchmark*\""
},
"version": "2.0.16"
}