Comparing version 2.0.21 to 3.0.0
@@ -0,1 +1,8 @@ | ||
### 3.0 | ||
- removes node 8 support | ||
- add z/OS (os390) support | ||
- environment variables to configure pidusage (`PIDUSAGE_USE_PS`, `PIDUSAGE_MAXAGE`, `PIDUSAGE_SILENT`) | ||
- use a default Date when `uptime` returns `undefined` | ||
### 2.0.17 | ||
@@ -2,0 +9,0 @@ |
'use strict' | ||
var stats = require('./lib/stats') | ||
const stats = require('./lib/stats') | ||
@@ -24,2 +24,7 @@ /** | ||
options = Object.assign({ | ||
usePs: process.env.PIDUSAGE_USE_PS, | ||
maxage: process.env.PIDUSAGE_MAXAGE | ||
}, options) | ||
if (typeof callback === 'function') { | ||
@@ -26,0 +31,0 @@ stats(pids, options, callback) |
'use strict' | ||
var spawn = require('child_process').spawn | ||
const spawn = require('child_process').spawn | ||
@@ -17,6 +17,6 @@ /** | ||
var executed = false | ||
var ch = spawn(cmd, args, options) | ||
var stdout = '' | ||
var stderr = '' | ||
let executed = false | ||
const ch = spawn(cmd, args, options) | ||
let stdout = '' | ||
let stderr = '' | ||
@@ -23,0 +23,0 @@ ch.stdout.on('data', function (d) { |
@@ -1,5 +0,5 @@ | ||
var os = require('os') | ||
var fs = require('fs') | ||
var exec = require('child_process').exec | ||
var parallel = require('./parallel') | ||
const os = require('os') | ||
const fs = require('fs') | ||
const exec = require('child_process').exec | ||
const parallel = require('./parallel') | ||
@@ -44,4 +44,6 @@ /** | ||
if (err || uptime === undefined) { | ||
console.warn("[pidusage] We couldn't find uptime from /proc/uptime, using os.uptime() value") | ||
return next(null, os.uptime()) | ||
if (!process.env.PIDUSAGE_SILENT) { | ||
console.warn("[pidusage] We couldn't find uptime from /proc/uptime, using os.uptime() value") | ||
} | ||
return next(null, os.uptime() || (new Date() / 1000)) | ||
} | ||
@@ -76,3 +78,5 @@ | ||
if (error !== null) { | ||
console.error('Error while getting ' + keyword, error) | ||
if (!process.env.PIDUSAGE_SILENT) { | ||
console.error('Error while calling "getconf ' + keyword + '"', error) | ||
} | ||
return next(null, options.default) | ||
@@ -79,0 +83,0 @@ } |
@@ -10,7 +10,7 @@ // execute an array of asynchronous functions in parallel | ||
var keys | ||
let keys | ||
if (!Array.isArray(fns)) { keys = Object.keys(fns) } | ||
var length = keys ? keys.length : fns.length | ||
var pending = length | ||
var results = keys ? {} : [] | ||
const length = keys ? keys.length : fns.length | ||
let pending = length | ||
const results = keys ? {} : [] | ||
@@ -17,0 +17,0 @@ function each (i, err, result) { |
'use strict' | ||
var DEFAULT_MAXAGE = 60000 | ||
const DEFAULT_MAXAGE = 60000 | ||
var expiration = {} | ||
var history = {} | ||
var expireListeners = {} | ||
const expiration = {} | ||
const history = {} | ||
const expireListeners = {} | ||
var size = 0 | ||
var interval = null | ||
let size = 0 | ||
let interval = null | ||
@@ -57,6 +57,6 @@ function get (pid, maxage) { | ||
function runInvalidator () { | ||
var now = Date.now() | ||
var pids = Object.keys(expiration) | ||
for (var i = 0; i < pids.length; i++) { | ||
var pid = pids[i] | ||
const now = Date.now() | ||
const pids = Object.keys(expiration) | ||
for (let i = 0; i < pids.length; i++) { | ||
const pid = pids[i] | ||
if (expiration[pid] < now) { | ||
@@ -63,0 +63,0 @@ size-- |
@@ -1,9 +0,9 @@ | ||
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 | ||
const fs = require('fs') | ||
const path = require('path') | ||
const updateCpu = require('./helpers/cpu') | ||
const parallel = require('./helpers/parallel') | ||
const history = require('./history') | ||
let cpuInfo = null | ||
const Buffer = require('safe-buffer').Buffer | ||
const SIZE = 1024 // if the stat file is bigger then this I'll buy you a drink | ||
@@ -24,3 +24,3 @@ function noop () {} | ||
function readUntilEnd (fd, buf, cb) { | ||
var firstRead = false | ||
let firstRead = false | ||
if (typeof buf === 'function') { | ||
@@ -38,3 +38,3 @@ cb = buf | ||
var data = Buffer.concat([buf, buffer], firstRead ? bytesRead : buf.length + bytesRead) | ||
const data = Buffer.concat([buf, buffer], firstRead ? bytesRead : buf.length + bytesRead) | ||
if (bytesRead === SIZE) { | ||
@@ -50,4 +50,4 @@ readUntilEnd(fd, data, cb) | ||
function readProcFile (pid, options, done) { | ||
var hst = history.get(pid, options.maxage) | ||
var again = false | ||
let hst = history.get(pid, options.maxage) | ||
let again = false | ||
if (hst === undefined) { | ||
@@ -76,8 +76,8 @@ again = true | ||
var infos = buffer.toString('utf8') | ||
var date = Date.now() | ||
let infos = buffer.toString('utf8') | ||
const 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(')') | ||
const index = infos.lastIndexOf(')') | ||
infos = infos.substr(index + 2).split(' ') | ||
@@ -87,3 +87,3 @@ | ||
// In kernels before Linux 2.6, start was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks | ||
var stat = { | ||
const stat = { | ||
ppid: parseInt(infos[1]), | ||
@@ -100,11 +100,11 @@ utime: parseFloat(infos[11]) * 1000 / cpuInfo.clockTick, | ||
var memory = stat.rss * cpuInfo.pageSize | ||
const memory = stat.rss * cpuInfo.pageSize | ||
// https://stackoverflow.com/a/16736599/3921589 | ||
var childrens = options.childrens ? stat.cutime + stat.cstime : 0 | ||
const 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) | ||
const total = (stat.stime - (hst.stime || 0) + stat.utime - (hst.utime || 0) + childrens) | ||
// 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 | ||
const seconds = Math.abs(hst.uptime !== undefined ? stat.uptime - hst.uptime : stat.start - stat.uptime) | ||
const cpu = seconds > 0 ? (total / seconds) * 100 : 0 | ||
@@ -135,3 +135,3 @@ history.set(pid, stat, options.maxage, close) | ||
cpuInfo = result | ||
var fns = {} | ||
const fns = {} | ||
@@ -138,0 +138,0 @@ pids.forEach(function (pid, i) { |
'use strict' | ||
var os = require('os') | ||
var bin = require('./bin') | ||
var history = require('./history') | ||
const os = require('os') | ||
const bin = require('./bin') | ||
const history = require('./history') | ||
var PLATFORM = os.platform() | ||
const PLATFORM = os.platform() | ||
function parseTime (timestr, centisec) { | ||
var time = 0 | ||
var tpart = timestr.split(/-|:|\./) | ||
var i = tpart.length - 1 | ||
let time = 0 | ||
const tpart = timestr.split(/-|:|\./) | ||
let i = tpart.length - 1 | ||
if (i >= 0 && centisec && PLATFORM === 'darwin') { | ||
@@ -38,4 +38,4 @@ time += parseInt(tpart[i--], 10) * 10 | ||
function ps (pids, options, done) { | ||
var pArg = pids.join(',') | ||
var args = ['-o', 'etime,pid,ppid,pcpu,rss,time', '-p', pArg] | ||
const pArg = pids.join(',') | ||
let args = ['-o', 'etime,pid,ppid,pcpu,rss,time', '-p', pArg] | ||
@@ -47,3 +47,10 @@ if (PLATFORM === 'aix') { | ||
bin('ps', args, function (err, stdout, code) { | ||
if (err) return done(err) | ||
if (err) { | ||
if (PLATFORM === 'os390' && /no matching processes found/.test(err)) { | ||
err = new Error('No matching pid found') | ||
err.code = 'ENOENT' | ||
} | ||
return done(err) | ||
} | ||
if (code === 1) { | ||
@@ -57,3 +64,3 @@ const error = new Error('No matching pid found') | ||
} | ||
var date = Date.now() | ||
const date = Date.now() | ||
@@ -92,5 +99,5 @@ // Example of stdout on *nix. | ||
var statistics = {} | ||
for (var i = 1; i < stdout.length; i++) { | ||
var line = stdout[i].trim().split(/\s+/) | ||
const statistics = {} | ||
for (let i = 1; i < stdout.length; i++) { | ||
const line = stdout[i].trim().split(/\s+/) | ||
@@ -101,15 +108,15 @@ if (!line || line.length !== 6) { | ||
var pid = parseInt(line[1], 10) | ||
var hst = history.get(pid, options.maxage) | ||
const pid = parseInt(line[1], 10) | ||
let 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) | ||
const ppid = parseInt(line[2], 10) | ||
const memory = parseInt(line[4], 10) * 1024 | ||
const etime = parseTime(line[0]) | ||
const ctime = parseTime(line[5], true) | ||
var total = (ctime - (hst.ctime || 0)) | ||
const 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 | ||
const seconds = Math.abs(hst.elapsed !== undefined ? etime - hst.elapsed : etime) | ||
const cpu = seconds > 0 ? (total / seconds) * 100 : 0 | ||
@@ -116,0 +123,0 @@ statistics[pid] = { |
'use strict' | ||
var fs = require('fs') | ||
var os = require('os') | ||
const fs = require('fs') | ||
const os = require('os') | ||
var platformToMethod = { | ||
const platformToMethod = { | ||
aix: 'ps', | ||
@@ -12,2 +12,3 @@ android: 'procfile', | ||
freebsd: 'ps', | ||
os390: 'ps', | ||
linux: 'procfile', | ||
@@ -19,4 +20,4 @@ netbsd: 'procfile', | ||
var ps = require('./ps') | ||
var platform = os.platform() | ||
const ps = require('./ps') | ||
let platform = os.platform() | ||
@@ -31,3 +32,3 @@ if (fs.existsSync('/etc/alpine-release')) { | ||
var stat | ||
let stat | ||
try { | ||
@@ -51,3 +52,3 @@ stat = require('./' + platformToMethod[platform]) | ||
function get (pids, options, callback) { | ||
var fn = stat | ||
let fn = stat | ||
if (platform !== 'win' && options.usePs === true) { | ||
@@ -61,3 +62,3 @@ fn = ps | ||
var single = false | ||
let single = false | ||
if (!Array.isArray(pids)) { | ||
@@ -72,3 +73,3 @@ single = true | ||
for (var i = 0; i < pids.length; i++) { | ||
for (let i = 0; i < pids.length; i++) { | ||
pids[i] = parseInt(pids[i], 10) | ||
@@ -75,0 +76,0 @@ if (isNaN(pids[i]) || pids[i] < 0) { |
'use strict' | ||
var os = require('os') | ||
var bin = require('./bin') | ||
var history = require('./history') | ||
const os = require('os') | ||
const bin = require('./bin') | ||
const 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 | ||
const year = datestr.substring(0, 4) | ||
const month = datestr.substring(4, 6) | ||
const day = datestr.substring(6, 8) | ||
const hour = datestr.substring(8, 10) | ||
const minutes = datestr.substring(10, 12) | ||
const seconds = datestr.substring(12, 14) | ||
const useconds = datestr.substring(15, 21) | ||
const sign = datestr.substring(21, 22) | ||
const tmz = parseInt(datestr.substring(22, 25), 10) | ||
const tmzh = Math.floor(tmz / 60) | ||
const tmzm = tmz % 60 | ||
@@ -35,8 +35,8 @@ return new Date( | ||
function wmic (pids, options, done) { | ||
var whereClause = 'ProcessId=' + pids[0] | ||
for (var i = 1; i < pids.length; i++) { | ||
let whereClause = 'ProcessId=' + pids[0] | ||
for (let i = 1; i < pids.length; i++) { | ||
whereClause += ' or ' + 'ProcessId=' + pids[i] | ||
} | ||
var args = [ | ||
const args = [ | ||
'PROCESS', | ||
@@ -61,7 +61,8 @@ 'where', | ||
} | ||
var date = Date.now() | ||
const 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()) | ||
// Fallback on current date when uptime is not allowed (see https://github.com/soyuka/pidusage/pull/130) | ||
const uptime = Math.floor(os.uptime() || (date / 1000)) | ||
@@ -83,6 +84,6 @@ // Example of stdout on Windows 10 | ||
var again = false | ||
var statistics = {} | ||
for (var i = 1; i < stdout.length; i++) { | ||
var line = stdout[i].trim().split(/\s+/) | ||
let again = false | ||
const statistics = {} | ||
for (let i = 1; i < stdout.length; i++) { | ||
const line = stdout[i].trim().split(/\s+/) | ||
@@ -93,10 +94,10 @@ if (!line || line.length !== 6) { | ||
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) | ||
const creation = parseDate(line[0]) | ||
const ppid = parseInt(line[2], 10) | ||
const pid = parseInt(line[3], 10) | ||
const kerneltime = Math.round(parseInt(line[1], 10) / 10000) | ||
const usertime = Math.round(parseInt(line[4], 10) / 10000) | ||
const memory = parseInt(line[5], 10) | ||
var hst = history.get(pid, options.maxage) | ||
let hst = history.get(pid, options.maxage) | ||
if (hst === undefined) { | ||
@@ -108,6 +109,6 @@ again = true | ||
// process usage since last call | ||
var total = (kerneltime + usertime - hst.ctime) / 1000 | ||
const 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 | ||
const seconds = uptime - hst.uptime | ||
const cpu = seconds > 0 ? (total / seconds) * 100 : 0 | ||
@@ -114,0 +115,0 @@ history.set(pid, { ctime: usertime + kerneltime, uptime: uptime }, options.maxage) |
{ | ||
"name": "pidusage", | ||
"version": "2.0.21", | ||
"version": "3.0.0", | ||
"description": "Cross-platform process cpu % and memory usage of a PID", | ||
@@ -21,3 +21,3 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">=8" | ||
"node": ">=10" | ||
}, | ||
@@ -27,3 +27,2 @@ "scripts": { | ||
"test": "nyc ava -m \"!*benchmark*\"", | ||
"alpine": "docker run -v $(pwd):/var/pidusage pidusage:latest npm test", | ||
"coverage": "codecov", | ||
@@ -42,3 +41,3 @@ "bench": "ava -m \"*benchmark*\"" | ||
"pify": "^3.0.0", | ||
"standard": "^14.3.4", | ||
"standard": "^16.0.4", | ||
"string-to-stream": "^1.1.1", | ||
@@ -45,0 +44,0 @@ "through": "^2.3.8", |
# 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) | ||
[![Lint](https://github.com/soyuka/pidusage/workflows/lint/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:lint+branch:main) | ||
[![MacOS](https://github.com/soyuka/pidusage/workflows/test-macos/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:test-macos+branch:main) | ||
[![Ubuntu](https://github.com/soyuka/pidusage/workflows/linux/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:linux+branch:main) | ||
[![Windows](https://github.com/soyuka/pidusage/workflows/test-windows/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:test-windows+branch:main) | ||
[![Alpine](https://github.com/soyuka/pidusage/workflows/test-alpine/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:test-alpine+branch:main) | ||
[![Code coverage](https://img.shields.io/codecov/c/github/soyuka/pidusage/master.svg)](https://codecov.io/gh/soyuka/pidusage) | ||
@@ -159,4 +162,16 @@ [![npm version](https://img.shields.io/npm/v/pidusage.svg)](https://www.npmjs.com/package/pidusage) | ||
| pids | <code>Number</code> \| <code>Array.<Number></code> \| <code>String</code> \| <code>Array.<String></code> | A pid or a list of pids. | | ||
| [options] | <code>object</code> | Options object. See the table below. | | ||
| [callback] | <code>function</code> | Called when the statistics are ready. If not provided a promise is returned instead. | | ||
### options | ||
Setting the options programatically will override environment variables | ||
| Param | Type | Environment variable | Default | Description | | ||
| --- | --- | --- | --- | --- | | ||
| [usePs] | <code>boolean</code> | `PIDUSAGE_USE_PS`| `false` | When true uses `ps` instead of proc files to fetch process information | | ||
| [maxage] | <code>number</code> | `PIDUSAGE_MAXAGE`| `60000` | Max age of a process on history. | | ||
`PIDUSAGE_SILENT=1` can be used to remove every console message triggered by pidusage. | ||
### pidusage.clear() | ||
@@ -163,0 +178,0 @@ |
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances 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
34360
685
205
9