feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

21
api.hyungi.net/node_modules/pidusage/LICENSE generated vendored Normal file
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.

204
api.hyungi.net/node_modules/pidusage/README.md generated vendored Normal file
View File

@@ -0,0 +1,204 @@
# 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)
[![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')
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
// }
cb()
})
// 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
// }
// Avoid using setInterval as they could overlap with asynchronous processing
function compute(cb) {
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
// }
cb()
})
}
function interval(time) {
setTimeout(function() {
compute(function() {
interval(time)
})
}, time)
}
// Compute statistics every second:
interval(1000)
// Above example using async/await
const compute = async () => {
const stats = await pidusage(process.pid)
// do something
}
// Compute statistics every second:
const interval = async (time) => {
setTimeout(async () => {
await compute()
interval(time)
}, time)
}
interval(1000)
```
## 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].
By default, pidusage will use `procfile` parsing on most unix systems. If you want to use `ps` instead use the `usePs` option:
```
pidusage(pid, {usePs: true})
```
## 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. |
| [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()
If needed this function can be used to delete all in-memory metrics and clear the event loop. This is not necessary before exiting as the interval we're registring does not hold up the event loop.
## 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

43
api.hyungi.net/node_modules/pidusage/index.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
'use strict'
const 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 = {}
}
options = Object.assign({
usePs: /^true$/i.test(process.env.PIDUSAGE_USE_PS),
maxage: process.env.PIDUSAGE_MAXAGE
}, 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
module.exports.clear = require('./lib/history').clear

48
api.hyungi.net/node_modules/pidusage/lib/bin.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
'use strict'
const 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
}
let executed = false
const ch = spawn(cmd, args, options)
let stdout = ''
let 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

View File

@@ -0,0 +1,91 @@
const os = require('os')
const fs = require('fs')
const exec = require('child_process').exec
const 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) {
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))
}
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) {
if (!process.env.PIDUSAGE_SILENT) {
console.error('Error while calling "getconf ' + keyword + '"', error)
}
return next(null, options.default)
}
stdout = parseInt(stdout)
if (!isNaN(stdout)) {
return next(null, stdout)
}
return next(null, options.default)
})
}

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 = {}
}
let keys
if (!Array.isArray(fns)) { keys = Object.keys(fns) }
const length = keys ? keys.length : fns.length
let pending = length
const 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

92
api.hyungi.net/node_modules/pidusage/lib/history.js generated vendored Normal file
View File

@@ -0,0 +1,92 @@
'use strict'
const DEFAULT_MAXAGE = 60000
const expiration = {}
const history = {}
const expireListeners = {}
let size = 0
let 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)
if (typeof interval.unref === 'function') {
interval.unref()
}
}
return
}
if (interval !== null) {
clearInterval(interval)
interval = null
}
}
function runInvalidator () {
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) {
size--
if (expireListeners[pid]) {
expireListeners[pid](history[pid])
}
delete history[pid]
delete expiration[pid]
delete expireListeners[pid]
}
}
sheduleInvalidator()
}
function deleteLoop (obj) { for (const i in obj) { delete obj[i] } }
function clear () {
if (interval !== null) {
clearInterval(interval)
interval = null
}
deleteLoop(history)
deleteLoop(expiration)
deleteLoop(expireListeners)
}
module.exports = {
get: get,
set: set,
clear: clear
}

141
api.hyungi.net/node_modules/pidusage/lib/procfile.js generated vendored Normal file
View File

@@ -0,0 +1,141 @@
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
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) {
let 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
}
const 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) {
let hst = history.get(pid, options.maxage)
let 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 matching pid found'
}
return done(err, null)
}
if (err) {
return done(err)
}
readUntilEnd(fd, function (err, buffer) {
if (err) {
return done(err)
}
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) ...)
const 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
const stat = {
ppid: parseInt(infos[1]),
utime: parseFloat(infos[11]) * 1000 / cpuInfo.clockTick,
stime: parseFloat(infos[12]) * 1000 / cpuInfo.clockTick,
cutime: parseFloat(infos[13]) * 1000 / cpuInfo.clockTick,
cstime: parseFloat(infos[14]) * 1000 / cpuInfo.clockTick,
start: parseFloat(infos[19]) * 1000 / cpuInfo.clockTick,
rss: parseFloat(infos[21]),
uptime: cpuInfo.uptime * 1000,
fd: fd
}
const memory = stat.rss * cpuInfo.pageSize
// https://stackoverflow.com/a/16736599/3921589
const childrens = options.childrens ? stat.cutime + stat.cstime : 0
// process usage since last call in seconds
const total = (stat.stime - (hst.stime || 0) + stat.utime - (hst.utime || 0) + childrens)
// time elapsed between calls in seconds
const seconds = Math.abs(hst.uptime !== undefined ? stat.uptime - hst.uptime : stat.start - stat.uptime)
const 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,
elapsed: stat.uptime - stat.start,
timestamp: date,
pid: pid,
ppid: stat.ppid
})
})
})
}
function procfile (pids, options, done) {
updateCpu(cpuInfo, function (err, result) {
if (err) return done(err)
cpuInfo = result
const fns = {}
pids.forEach(function (pid, i) {
fns[pid] = function (cb) {
readProcFile(pid, options, cb)
}
})
parallel(fns, { graceful: true }, done)
})
}
module.exports = procfile

135
api.hyungi.net/node_modules/pidusage/lib/ps.js generated vendored Normal file
View File

@@ -0,0 +1,135 @@
'use strict'
const os = require('os')
const bin = require('./bin')
const history = require('./history')
const PLATFORM = os.platform()
function parseTime (timestr, centisec) {
let time = 0
const tpart = timestr.split(/-|:|\./)
let 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) {
const pArg = pids.join(',')
let args = ['-o', 'etime,pid,ppid,pcpu,rss,time', '-p', pArg]
if (PLATFORM === 'aix' || PLATFORM === 'os400') {
args = ['-o', 'etime,pid,ppid,pcpu,rssize,time', '-p', pArg]
}
bin('ps', args, function (err, stdout, code) {
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) {
const error = new Error('No matching pid found')
error.code = 'ENOENT'
return done(error)
}
if (code !== 0) {
return done(new Error('pidusage ps command exited with code ' + code))
}
const 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)
const statistics = {}
for (let i = 1; i < stdout.length; i++) {
const line = stdout[i].trim().split(/\s+/)
if (!line || line.length !== 6) {
continue
}
const pid = parseInt(line[1], 10)
let hst = history.get(pid, options.maxage)
if (hst === undefined) hst = {}
const ppid = parseInt(line[2], 10)
const memory = parseInt(line[4], 10) * 1024
const etime = parseTime(line[0])
const ctime = parseTime(line[5], true)
const total = (ctime - (hst.ctime || 0))
// time elapsed between calls in seconds
const seconds = Math.abs(hst.elapsed !== undefined ? etime - hst.elapsed : etime)
const 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

95
api.hyungi.net/node_modules/pidusage/lib/stats.js generated vendored Normal file
View File

@@ -0,0 +1,95 @@
'use strict'
const fs = require('fs')
const os = require('os')
const requireMap = {
ps: () => require('./ps'),
procfile: () => require('./procfile'),
wmic: () => require('./wmic')
}
const platformToMethod = {
aix: 'ps',
os400: 'ps',
android: 'procfile',
alpine: 'procfile',
darwin: 'ps',
freebsd: 'ps',
os390: 'ps',
linux: 'procfile',
netbsd: 'procfile',
openbsd: 'ps',
sunos: 'ps',
win: 'wmic'
}
let platform = os.platform()
if (fs.existsSync('/etc/alpine-release')) {
platform = 'alpine'
}
if (platform.match(/^win/)) {
platform = 'win'
}
let stat
try {
stat = requireMap[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) {
let fn = stat
if (platform !== 'win' && options.usePs === true) {
fn = requireMap.ps()
}
if (fn === undefined) {
return callback(new Error(os.platform() + ' is not supported yet, please open an issue (https://github.com/soyuka/pidusage)'))
}
let 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 (let 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

133
api.hyungi.net/node_modules/pidusage/lib/wmic.js generated vendored Normal file
View File

@@ -0,0 +1,133 @@
'use strict'
const os = require('os')
const bin = require('./bin')
const history = require('./history')
function parseDate (datestr) {
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
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) {
let whereClause = 'ProcessId=' + pids[0]
for (let i = 1; i < pids.length; i++) {
whereClause += ' or ' + 'ProcessId=' + pids[i]
}
const 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) {
const error = new Error('No matching pid found')
error.code = 'ENOENT'
return done(error)
}
return done(err)
}
if (code !== 0) {
return done(new Error('pidusage wmic command exited with code ' + code))
}
const date = Date.now()
// Note: On Windows the returned value includes fractions of a second.
// Use Math.floor() to get whole seconds.
// 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))
// 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)
let again = false
const statistics = {}
for (let i = 1; i < stdout.length; i++) {
const line = stdout[i].trim().split(/\s+/)
if (!line || line.length !== 6) {
continue
}
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)
let hst = history.get(pid, options.maxage)
if (hst === undefined) {
again = true
hst = { ctime: kerneltime + usertime, uptime: uptime }
}
// process usage since last call
const total = (kerneltime + usertime - hst.ctime) / 1000
// time elapsed between calls in seconds
const seconds = uptime - hst.uptime
const 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

61
api.hyungi.net/node_modules/pidusage/package.json generated vendored Normal file
View File

@@ -0,0 +1,61 @@
{
"name": "pidusage",
"version": "3.0.2",
"description": "Cross-platform process cpu % and memory usage of a PID",
"license": "MIT",
"homepage": "https://github.com/soyuka/pidusage",
"repository": "github:soyuka/pidusage",
"bugs": {
"url": "https://github.com/soyuka/pidusage/issues"
},
"author": "soyuka",
"contributors": [
"Simone Primarosa <simonepri@outlook.com> (https://simoneprimarosa.com)"
],
"main": "index.js",
"files": [
"lib",
"index.js"
],
"engines": {
"node": ">=10"
},
"scripts": {
"lint": "standard",
"test": "nyc ava -m \"!*benchmark*\"",
"coverage": "codecov",
"bench": "ava -m \"*benchmark*\""
},
"dependencies": {
"safe-buffer": "^5.2.1"
},
"devDependencies": {
"ava": "^3.10.1",
"codecov": "^3.7.0",
"mockdate": "^2.0.5",
"mockery": "^2.1.0",
"nyc": "^15.1.0",
"pify": "^3.0.0",
"standard": "^16.0.4",
"string-to-stream": "^1.1.1",
"through": "^2.3.8",
"time-span": "^2.0.0"
},
"keywords": [
"pid",
"usage",
"ps",
"cpu",
"memory",
"proc"
],
"ava": {
"verbose": true
},
"nyc": {
"reporter": [
"lcovonly",
"text"
]
}
}