pm2-perfmonitor 2.1.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/app.js +40 -2
- package/lib/perf-sampler.js +1 -1
- package/lib/utils.js +14 -0
- package/package.json +3 -2
package/lib/app.js
CHANGED
|
@@ -6,6 +6,7 @@ const {
|
|
|
6
6
|
parseParamToNumber,
|
|
7
7
|
parseBool,
|
|
8
8
|
sleepAsync,
|
|
9
|
+
getSysCpuUsageByPid,
|
|
9
10
|
} = require('./utils')
|
|
10
11
|
const { defaultOptions } = require('./defaults')
|
|
11
12
|
const { sendMessage } = require('./message')
|
|
@@ -60,6 +61,12 @@ const cpuOverloadHistory = new Map()
|
|
|
60
61
|
const cpuOverloadRestartHistory = new Map()
|
|
61
62
|
const cpuOverloadRestartFailedHistory = new Map()
|
|
62
63
|
|
|
64
|
+
/**
|
|
65
|
+
* perf 样本是否采集中
|
|
66
|
+
* @type { Map<number,boolean> }
|
|
67
|
+
*/
|
|
68
|
+
const perfSamplingStats = new Map()
|
|
69
|
+
|
|
63
70
|
/**
|
|
64
71
|
* @param {'log' | 'info' | 'error' | 'warn'} type
|
|
65
72
|
*
|
|
@@ -152,18 +159,26 @@ const setCpuOverloadRestartFailedHistory = (pm_id) => {
|
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
161
|
|
|
162
|
+
let isProcessCheckerRunning = false
|
|
163
|
+
|
|
155
164
|
/**
|
|
156
165
|
* check process
|
|
157
166
|
*/
|
|
158
167
|
const processChecker = async () => {
|
|
168
|
+
if (isProcessCheckerRunning) return
|
|
169
|
+
|
|
159
170
|
try {
|
|
171
|
+
isProcessCheckerRunning = true
|
|
172
|
+
|
|
160
173
|
const apps = await listAppsAsync()
|
|
161
174
|
|
|
162
175
|
for (const app of apps) {
|
|
163
|
-
const { name, pm_id, monit, pm2_env
|
|
176
|
+
const { name, pid, pm_id, monit, pm2_env } = app
|
|
177
|
+
|
|
178
|
+
const sysCpuUsage = await getSysCpuUsageByPid(pid)
|
|
164
179
|
|
|
165
180
|
const appStatus = pm2_env?.status
|
|
166
|
-
const appCpuUsage =
|
|
181
|
+
const appCpuUsage = sysCpuUsage
|
|
167
182
|
|
|
168
183
|
// 非目标应用,跳过
|
|
169
184
|
if (
|
|
@@ -249,6 +264,8 @@ const processChecker = async () => {
|
|
|
249
264
|
)
|
|
250
265
|
|
|
251
266
|
if (enablePerfCollection) {
|
|
267
|
+
perfSamplingStats.set(pm_id, true)
|
|
268
|
+
|
|
252
269
|
await performPerfSampling({
|
|
253
270
|
pid,
|
|
254
271
|
moduleName: MODULE_NAME,
|
|
@@ -257,6 +274,8 @@ const processChecker = async () => {
|
|
|
257
274
|
sampleDuration: perfSampleDuration,
|
|
258
275
|
sampleFrequency: perfSampleFrequency,
|
|
259
276
|
})
|
|
277
|
+
|
|
278
|
+
perfSamplingStats.delete(pm_id)
|
|
260
279
|
}
|
|
261
280
|
|
|
262
281
|
try {
|
|
@@ -292,6 +311,8 @@ const processChecker = async () => {
|
|
|
292
311
|
}
|
|
293
312
|
} catch (err) {
|
|
294
313
|
logger('error', err)
|
|
314
|
+
} finally {
|
|
315
|
+
isProcessCheckerRunning = false
|
|
295
316
|
}
|
|
296
317
|
}
|
|
297
318
|
|
|
@@ -417,6 +438,23 @@ const runModule = () => {
|
|
|
417
438
|
return res.map((v) => `[${v[0]}]:${v[1]}`).join(' ; ')
|
|
418
439
|
},
|
|
419
440
|
})
|
|
441
|
+
|
|
442
|
+
Probe.metric({
|
|
443
|
+
name: 'Processes in Sampling (perf)',
|
|
444
|
+
value: () => {
|
|
445
|
+
const res = []
|
|
446
|
+
|
|
447
|
+
for (const [k, v] of perfSamplingStats) {
|
|
448
|
+
if (v === true) {
|
|
449
|
+
res.push(k)
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
if (!res.length) return 'N/A'
|
|
454
|
+
|
|
455
|
+
return res.join(', ')
|
|
456
|
+
},
|
|
457
|
+
})
|
|
420
458
|
}
|
|
421
459
|
|
|
422
460
|
runModule()
|
package/lib/perf-sampler.js
CHANGED
|
@@ -30,7 +30,7 @@ const execCommand = async (cmd, args, options = {}) => {
|
|
|
30
30
|
|
|
31
31
|
return true
|
|
32
32
|
} catch (err) {
|
|
33
|
-
console.error(`Command failed: ${cmd} ${args.join(' ')}`, err.message)
|
|
33
|
+
console.error(`Command failed: [${cmd} ${args.join(' ')}]`, err.message)
|
|
34
34
|
return false
|
|
35
35
|
}
|
|
36
36
|
}
|
package/lib/utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const pidusage = require('pidusage')
|
|
2
|
+
|
|
1
3
|
const parseParamToArray = (value, defaultVal = []) => {
|
|
2
4
|
if (Array.isArray(value)) return value
|
|
3
5
|
|
|
@@ -37,9 +39,21 @@ const sleepAsync = (duration = 0) => {
|
|
|
37
39
|
})
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
/**
|
|
43
|
+
* 获取指定进程的CPU使用率
|
|
44
|
+
* @param {string| number} pid
|
|
45
|
+
* @returns { Promise<number> } CPU 使用率
|
|
46
|
+
*/
|
|
47
|
+
const getSysCpuUsageByPid = async (pid) => {
|
|
48
|
+
const stats = await pidusage(pid)
|
|
49
|
+
|
|
50
|
+
return stats.cpu
|
|
51
|
+
}
|
|
52
|
+
|
|
40
53
|
module.exports = {
|
|
41
54
|
parseParamToArray,
|
|
42
55
|
parseParamToNumber,
|
|
43
56
|
parseBool,
|
|
44
57
|
sleepAsync,
|
|
58
|
+
getSysCpuUsageByPid,
|
|
45
59
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pm2-perfmonitor",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "A pm2 module for performance monitoring. Automatically detect zombie processes and restart it",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "elenh",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"execa": "^9.6.1",
|
|
46
46
|
"fs-extra": "^11.3.4",
|
|
47
|
+
"pidusage": "^4.0.1",
|
|
47
48
|
"pm2": "latest",
|
|
48
49
|
"pmx": "latest"
|
|
49
50
|
},
|
|
@@ -52,4 +53,4 @@
|
|
|
52
53
|
"cz-conventional-changelog": "^3.3.0",
|
|
53
54
|
"minimist": "^1.2.8"
|
|
54
55
|
}
|
|
55
|
-
}
|
|
56
|
+
}
|