systeminformation 5.9.7 → 5.9.8

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/processes.js CHANGED
@@ -1,1240 +1,1240 @@
1
- 'use strict';
2
- // @ts-check
3
- // ==================================================================================
4
- // processes.js
5
- // ----------------------------------------------------------------------------------
6
- // Description: System Information - library
7
- // for Node.js
8
- // Copyright: (c) 2014 - 2021
9
- // Author: Sebastian Hildebrandt
10
- // ----------------------------------------------------------------------------------
11
- // License: MIT
12
- // ==================================================================================
13
- // 10. Processes
14
- // ----------------------------------------------------------------------------------
15
-
16
- const os = require('os');
17
- const fs = require('fs');
18
- const path = require('path');
19
- const exec = require('child_process').exec;
20
- const execSync = require('child_process').execSync;
21
-
22
- const util = require('./util');
23
-
24
- let _platform = process.platform;
25
-
26
- const _linux = (_platform === 'linux');
27
- const _darwin = (_platform === 'darwin');
28
- const _windows = (_platform === 'win32');
29
- const _freebsd = (_platform === 'freebsd');
30
- const _openbsd = (_platform === 'openbsd');
31
- const _netbsd = (_platform === 'netbsd');
32
- const _sunos = (_platform === 'sunos');
33
-
34
- const _processes_cpu = {
35
- all: 0,
36
- all_utime: 0,
37
- all_stime: 0,
38
- list: {},
39
- ms: 0,
40
- result: {}
41
- };
42
- const _services_cpu = {
43
- all: 0,
44
- all_utime: 0,
45
- all_stime: 0,
46
- list: {},
47
- ms: 0,
48
- result: {}
49
- };
50
- const _process_cpu = {
51
- all: 0,
52
- all_utime: 0,
53
- all_stime: 0,
54
- list: {},
55
- ms: 0,
56
- result: {}
57
- };
58
-
59
- const _winStatusValues = {
60
- '0': 'unknown',
61
- '1': 'other',
62
- '2': 'ready',
63
- '3': 'running',
64
- '4': 'blocked',
65
- '5': 'suspended blocked',
66
- '6': 'suspended ready',
67
- '7': 'terminated',
68
- '8': 'stopped',
69
- '9': 'growing',
70
- };
71
-
72
-
73
- function parseTimeWin(time) {
74
- time = time || '';
75
- if (time) {
76
- return (time.substr(0, 4) + '-' + time.substr(4, 2) + '-' + time.substr(6, 2) + ' ' + time.substr(8, 2) + ':' + time.substr(10, 2) + ':' + time.substr(12, 2));
77
- } else {
78
- return '';
79
- }
80
- }
81
-
82
- function parseTimeUnix(time) {
83
- let result = time;
84
- let parts = time.replace(/ +/g, ' ').split(' ');
85
- if (parts.length === 5) {
86
- result = parts[4] + '-' + ('0' + ('JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.indexOf(parts[1].toUpperCase()) / 3 + 1)).slice(-2) + '-' + ('0' + parts[2]).slice(-2) + ' ' + parts[3];
87
- }
88
- return result;
89
- }
90
-
91
- // --------------------------
92
- // PS - services
93
- // pass a comma separated string with services to check (mysql, apache, postgresql, ...)
94
- // this function gives an array back, if the services are running.
95
-
96
- function services(srv, callback) {
97
-
98
- // fallback - if only callback is given
99
- if (util.isFunction(srv) && !callback) {
100
- callback = srv;
101
- srv = '';
102
- }
103
-
104
- return new Promise((resolve) => {
105
- process.nextTick(() => {
106
- if (typeof srv !== 'string') {
107
- if (callback) { callback([]); }
108
- return resolve([]);
109
- }
110
-
111
- if (srv) {
112
- let srvString = '';
113
- srvString.__proto__.toLowerCase = util.stringToLower;
114
- srvString.__proto__.replace = util.stringReplace;
115
- srvString.__proto__.trim = util.stringTrim;
116
-
117
- const s = util.sanitizeShellString(srv);
118
- for (let i = 0; i <= util.mathMin(s.length, 2000); i++) {
119
- if (!(s[i] === undefined)) {
120
- srvString = srvString + s[i];
121
- }
122
- }
123
-
124
- srvString = srvString.trim().toLowerCase().replace(/, /g, '|').replace(/,+/g, '|');
125
- if (srvString === '') {
126
- srvString = '*';
127
- }
128
- if (util.isPrototypePolluted() && srvString !== '*') {
129
- srvString = '------';
130
- }
131
- let srvs = srvString.split('|');
132
- let result = [];
133
- let dataSrv = [];
134
- // let allSrv = [];
135
-
136
- if (_linux || _freebsd || _openbsd || _netbsd || _darwin) {
137
- if ((_linux || _freebsd || _openbsd || _netbsd) && srvString === '*') {
138
- try {
139
- const tmpsrv = execSync('systemctl --type=service --no-legend 2> /dev/null').toString().split('\n');
140
- srvs = [];
141
- for (const s of tmpsrv) {
142
- const name = s.split('.service')[0];
143
- if (name) {
144
- srvs.push(name);
145
- }
146
- }
147
- srvString = srvs.join('|');
148
- } catch (d) {
149
- try {
150
- srvString = '';
151
- const tmpsrv = execSync('service --status-all 2> /dev/null').toString().split('\n');
152
- for (const s of tmpsrv) {
153
- const parts = s.split(']');
154
- if (parts.length === 2) {
155
- srvString += (srvString !== '' ? '|' : '') + parts[1].trim();
156
- // allSrv.push({ name: parts[1].trim(), running: parts[0].indexOf('+') > 0 });
157
- }
158
- }
159
- srvs = srvString.split('|');
160
- } catch (e) {
161
- try {
162
- const srvStr = execSync('ls /etc/init.d/ -m 2> /dev/null').toString().split('\n').join('');
163
- srvString = '';
164
- if (srvStr) {
165
- const tmpsrv = srvStr.split(',');
166
- for (const s of tmpsrv) {
167
- const name = s.trim();
168
- if (name) {
169
- srvString += (srvString !== '' ? '|' : '') + name;
170
- // allSrv.push({ name: name, running: null });
171
- }
172
- }
173
- srvs = srvString.split('|');
174
- }
175
- } catch (f) {
176
- // allSrv = [];
177
- srvString = '';
178
- srvs = [];
179
- }
180
- }
181
- }
182
- }
183
- if ((_darwin) && srvString === '*') { // service enumeration not yet suported on mac OS
184
- if (callback) { callback(result); }
185
- resolve(result);
186
- }
187
- let args = (_darwin) ? ['-caxo', 'pcpu,pmem,pid,command'] : ['-axo', 'pcpu,pmem,pid,command'];
188
- if (srvString !== '' && srvs.length > 0) {
189
- util.execSafe('ps', args).then((stdout) => {
190
- if (stdout) {
191
- let lines = stdout.replace(/ +/g, ' ').replace(/,+/g, '.').split('\n');
192
- srvs.forEach(function (srv) {
193
- let ps;
194
- if (_darwin) {
195
- ps = lines.filter(function (e) {
196
- return (e.toLowerCase().indexOf(srv) !== -1);
197
- });
198
-
199
- } else {
200
- ps = lines.filter(function (e) {
201
- return (e.toLowerCase().indexOf(' ' + srv + ':') !== -1) || (e.toLowerCase().indexOf('/' + srv) !== -1);
202
- });
203
- }
204
- // let singleSrv = allSrv.filter(item => { return item.name === srv; });
205
- const pids = [];
206
- for (const p of ps) {
207
- const pid = p.trim().split(' ')[2];
208
- if (pid) {
209
- pids.push(parseInt(pid, 10));
210
- }
211
- }
212
- result.push({
213
- name: srv,
214
- // running: (allSrv.length && singleSrv.length && singleSrv[0].running !== null ? singleSrv[0].running : ps.length > 0),
215
- running: ps.length > 0,
216
- startmode: '',
217
- pids: pids,
218
- cpu: parseFloat((ps.reduce(function (pv, cv) {
219
- return pv + parseFloat(cv.trim().split(' ')[0]);
220
- }, 0)).toFixed(2)),
221
- mem: parseFloat((ps.reduce(function (pv, cv) {
222
- return pv + parseFloat(cv.trim().split(' ')[1]);
223
- }, 0)).toFixed(2))
224
- });
225
- });
226
- if (_linux) {
227
- // calc process_cpu - ps is not accurate in linux!
228
- let cmd = 'cat /proc/stat | grep "cpu "';
229
- for (let i in result) {
230
- for (let j in result[i].pids) {
231
- cmd += (';cat /proc/' + result[i].pids[j] + '/stat');
232
- }
233
- }
234
- exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
235
- let curr_processes = stdout.toString().split('\n');
236
-
237
- // first line (all - /proc/stat)
238
- let all = parseProcStat(curr_processes.shift());
239
-
240
- // process
241
- let list_new = {};
242
- let resultProcess = {};
243
- for (let i = 0; i < curr_processes.length; i++) {
244
- resultProcess = calcProcStatLinux(curr_processes[i], all, _services_cpu);
245
-
246
- if (resultProcess.pid) {
247
- let listPos = -1;
248
- for (let i in result) {
249
- for (let j in result[i].pids) {
250
- if (parseInt(result[i].pids[j]) === parseInt(resultProcess.pid)) {
251
- listPos = i;
252
- }
253
- }
254
- }
255
- if (listPos >= 0) {
256
- result[listPos].cpu += resultProcess.cpuu + resultProcess.cpus;
257
- }
258
-
259
- // save new values
260
- list_new[resultProcess.pid] = {
261
- cpuu: resultProcess.cpuu,
262
- cpus: resultProcess.cpus,
263
- utime: resultProcess.utime,
264
- stime: resultProcess.stime,
265
- cutime: resultProcess.cutime,
266
- cstime: resultProcess.cstime
267
- };
268
- }
269
- }
270
-
271
- // store old values
272
- _services_cpu.all = all;
273
- // _services_cpu.list = list_new;
274
- _services_cpu.list = Object.assign({}, list_new);
275
- _services_cpu.ms = Date.now() - _services_cpu.ms;
276
- // _services_cpu.result = result;
277
- _services_cpu.result = Object.assign({}, result);
278
- if (callback) { callback(result); }
279
- resolve(result);
280
- });
281
- } else {
282
- if (callback) { callback(result); }
283
- resolve(result);
284
- }
285
- } else {
286
- args = ['-o', 'comm'];
287
- util.execSafe('ps', args).then((stdout) => {
288
- if (stdout) {
289
- let lines = stdout.replace(/ +/g, ' ').replace(/,+/g, '.').split('\n');
290
- srvs.forEach(function (srv) {
291
- let ps = lines.filter(function (e) {
292
- return e.indexOf(srv) !== -1;
293
- });
294
- result.push({
295
- name: srv,
296
- running: ps.length > 0,
297
- startmode: '',
298
- cpu: 0,
299
- mem: 0
300
- });
301
- });
302
- if (callback) { callback(result); }
303
- resolve(result);
304
- } else {
305
- srvs.forEach(function (srv) {
306
- result.push({
307
- name: srv,
308
- running: false,
309
- startmode: '',
310
- cpu: 0,
311
- mem: 0
312
- });
313
- });
314
- if (callback) { callback(result); }
315
- resolve(result);
316
- }
317
- });
318
- }
319
- });
320
- } else {
321
- if (callback) { callback(result); }
322
- resolve(result);
323
- }
324
- }
325
- if (_windows) {
326
- try {
327
- util.wmic('service get /value').then((stdout, error) => {
328
- if (!error) {
329
- let serviceSections = stdout.split(/\n\s*\n/);
330
- for (let i = 0; i < serviceSections.length; i++) {
331
- if (serviceSections[i].trim() !== '') {
332
- let lines = serviceSections[i].trim().split('\r\n');
333
- let srvName = util.getValue(lines, 'Name', '=', true).toLowerCase();
334
- let srvCaption = util.getValue(lines, 'Caption', '=', true).toLowerCase();
335
- let started = util.getValue(lines, 'Started', '=', true);
336
- let startMode = util.getValue(lines, 'StartMode', '=', true);
337
- let pid = util.getValue(lines, 'ProcessId', '=', true);
338
- if (srvString === '*' || srvs.indexOf(srvName) >= 0 || srvs.indexOf(srvCaption) >= 0) {
339
- result.push({
340
- name: srvName,
341
- running: (started === 'TRUE'),
342
- startmode: startMode,
343
- pids: [pid],
344
- cpu: 0,
345
- mem: 0
346
- });
347
- dataSrv.push(srvName);
348
- dataSrv.push(srvCaption);
349
- }
350
- }
351
- }
352
- if (srvString !== '*') {
353
- let srvsMissing = srvs.filter(function (e) {
354
- return dataSrv.indexOf(e) === -1;
355
- });
356
- srvsMissing.forEach(function (srvName) {
357
- result.push({
358
- name: srvName,
359
- running: false,
360
- startmode: '',
361
- pids: [],
362
- cpu: 0,
363
- mem: 0
364
- });
365
- });
366
- }
367
- if (callback) { callback(result); }
368
- resolve(result);
369
- } else {
370
- srvs.forEach(function (srvName) {
371
- result.push({
372
- name: srvName,
373
- running: false,
374
- startmode: '',
375
- cpu: 0,
376
- mem: 0
377
- });
378
- });
379
- if (callback) { callback(result); }
380
- resolve(result);
381
- }
382
- });
383
- } catch (e) {
384
- if (callback) { callback(result); }
385
- resolve(result);
386
- }
387
- }
388
- } else {
389
- if (callback) { callback([]); }
390
- resolve([]);
391
- }
392
- });
393
- });
394
- }
395
-
396
- exports.services = services;
397
-
398
- function parseProcStat(line) {
399
- let parts = line.replace(/ +/g, ' ').split(' ');
400
- let user = (parts.length >= 2 ? parseInt(parts[1]) : 0);
401
- let nice = (parts.length >= 3 ? parseInt(parts[2]) : 0);
402
- let system = (parts.length >= 4 ? parseInt(parts[3]) : 0);
403
- let idle = (parts.length >= 5 ? parseInt(parts[4]) : 0);
404
- let iowait = (parts.length >= 6 ? parseInt(parts[5]) : 0);
405
- let irq = (parts.length >= 7 ? parseInt(parts[6]) : 0);
406
- let softirq = (parts.length >= 8 ? parseInt(parts[7]) : 0);
407
- let steal = (parts.length >= 9 ? parseInt(parts[8]) : 0);
408
- let guest = (parts.length >= 10 ? parseInt(parts[9]) : 0);
409
- let guest_nice = (parts.length >= 11 ? parseInt(parts[10]) : 0);
410
- return user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice;
411
- }
412
-
413
- function calcProcStatLinux(line, all, _cpu_old) {
414
- let statparts = line.replace(/ +/g, ' ').split(')');
415
- if (statparts.length >= 2) {
416
- let parts = statparts[1].split(' ');
417
- if (parts.length >= 16) {
418
- let pid = parseInt(statparts[0].split(' ')[0]);
419
- let utime = parseInt(parts[12]);
420
- let stime = parseInt(parts[13]);
421
- let cutime = parseInt(parts[14]);
422
- let cstime = parseInt(parts[15]);
423
-
424
- // calc
425
- let cpuu = 0;
426
- let cpus = 0;
427
- if (_cpu_old.all > 0 && _cpu_old.list[pid]) {
428
- cpuu = (utime + cutime - _cpu_old.list[pid].utime - _cpu_old.list[pid].cutime) / (all - _cpu_old.all) * 100; // user
429
- cpus = (stime + cstime - _cpu_old.list[pid].stime - _cpu_old.list[pid].cstime) / (all - _cpu_old.all) * 100; // system
430
- } else {
431
- cpuu = (utime + cutime) / (all) * 100; // user
432
- cpus = (stime + cstime) / (all) * 100; // system
433
- }
434
- return {
435
- pid: pid,
436
- utime: utime,
437
- stime: stime,
438
- cutime: cutime,
439
- cstime: cstime,
440
- cpuu: cpuu,
441
- cpus: cpus
442
- };
443
- } else {
444
- return {
445
- pid: 0,
446
- utime: 0,
447
- stime: 0,
448
- cutime: 0,
449
- cstime: 0,
450
- cpuu: 0,
451
- cpus: 0
452
- };
453
- }
454
- } else {
455
- return {
456
- pid: 0,
457
- utime: 0,
458
- stime: 0,
459
- cutime: 0,
460
- cstime: 0,
461
- cpuu: 0,
462
- cpus: 0
463
- };
464
- }
465
- }
466
-
467
- function calcProcStatWin(procStat, all, _cpu_old) {
468
- // calc
469
- let cpuu = 0;
470
- let cpus = 0;
471
- if (_cpu_old.all > 0 && _cpu_old.list[procStat.pid]) {
472
- cpuu = (procStat.utime - _cpu_old.list[procStat.pid].utime) / (all - _cpu_old.all) * 100; // user
473
- cpus = (procStat.stime - _cpu_old.list[procStat.pid].stime) / (all - _cpu_old.all) * 100; // system
474
- } else {
475
- cpuu = (procStat.utime) / (all) * 100; // user
476
- cpus = (procStat.stime) / (all) * 100; // system
477
- }
478
- return {
479
- pid: procStat.pid,
480
- utime: cpuu > 0 ? procStat.utime : 0,
481
- stime: cpus > 0 ? procStat.stime : 0,
482
- cpuu: cpuu > 0 ? cpuu : 0,
483
- cpus: cpus > 0 ? cpus : 0
484
- };
485
- }
486
-
487
-
488
-
489
- // --------------------------
490
- // running processes
491
-
492
- function processes(callback) {
493
-
494
- let parsedhead = [];
495
-
496
- function getName(command) {
497
- command = command || '';
498
- let result = command.split(' ')[0];
499
- if (result.substr(-1) === ':') {
500
- result = result.substr(0, result.length - 1);
501
- }
502
- if (result.substr(0, 1) !== '[') {
503
- let parts = result.split('/');
504
- if (isNaN(parseInt(parts[parts.length - 1]))) {
505
- result = parts[parts.length - 1];
506
- } else {
507
- result = parts[0];
508
- }
509
- }
510
- return result;
511
- }
512
-
513
- function parseLine(line) {
514
-
515
- let offset = 0;
516
- let offset2 = 0;
517
-
518
- function checkColumn(i) {
519
- offset = offset2;
520
- if (parsedhead[i]) {
521
- offset2 = line.substring(parsedhead[i].to + offset, 10000).indexOf(' ');
522
- } else {
523
- offset2 = 10000;
524
- }
525
- }
526
-
527
- checkColumn(0);
528
- const pid = parseInt(line.substring(parsedhead[0].from + offset, parsedhead[0].to + offset2));
529
- checkColumn(1);
530
- const ppid = parseInt(line.substring(parsedhead[1].from + offset, parsedhead[1].to + offset2));
531
- checkColumn(2);
532
- const cpu = parseFloat(line.substring(parsedhead[2].from + offset, parsedhead[2].to + offset2).replace(/,/g, '.'));
533
- checkColumn(3);
534
- const mem = parseFloat(line.substring(parsedhead[3].from + offset, parsedhead[3].to + offset2).replace(/,/g, '.'));
535
- checkColumn(4);
536
- const priority = parseInt(line.substring(parsedhead[4].from + offset, parsedhead[4].to + offset2));
537
- checkColumn(5);
538
- const vsz = parseInt(line.substring(parsedhead[5].from + offset, parsedhead[5].to + offset2));
539
- checkColumn(6);
540
- const rss = parseInt(line.substring(parsedhead[6].from + offset, parsedhead[6].to + offset2));
541
- checkColumn(7);
542
- const nice = parseInt(line.substring(parsedhead[7].from + offset, parsedhead[7].to + offset2)) || 0;
543
- checkColumn(8);
544
- const started = parseTimeUnix(line.substring(parsedhead[8].from + offset, parsedhead[8].to + offset2).trim());
545
- checkColumn(9);
546
- let state = line.substring(parsedhead[9].from + offset, parsedhead[9].to + offset2).trim();
547
- state = (state[0] === 'R' ? 'running' : (state[0] === 'S' ? 'sleeping' : (state[0] === 'T' ? 'stopped' : (state[0] === 'W' ? 'paging' : (state[0] === 'X' ? 'dead' : (state[0] === 'Z' ? 'zombie' : ((state[0] === 'D' || state[0] === 'U') ? 'blocked' : 'unknown')))))));
548
- checkColumn(10);
549
- let tty = line.substring(parsedhead[10].from + offset, parsedhead[10].to + offset2).trim();
550
- if (tty === '?' || tty === '??') { tty = ''; }
551
- checkColumn(11);
552
- const user = line.substring(parsedhead[11].from + offset, parsedhead[11].to + offset2).trim();
553
- checkColumn(12);
554
- let cmdPath = '';
555
- let command = '';
556
- let params = '';
557
- let fullcommand = line.substring(parsedhead[12].from + offset, parsedhead[12].to + offset2).trim();
558
- if (fullcommand.substr(fullcommand.length - 1) === ']') { fullcommand = fullcommand.slice(0, -1); }
559
- if (fullcommand.substr(0, 1) === '[') { command = fullcommand.substring(1); }
560
- else {
561
- // try to figure out where parameter starts
562
- let firstParamPos = fullcommand.indexOf(' -');
563
- let firstParamPathPos = fullcommand.indexOf(' /');
564
- firstParamPos = (firstParamPos >= 0 ? firstParamPos : 10000);
565
- firstParamPathPos = (firstParamPathPos >= 0 ? firstParamPathPos : 10000);
566
- const firstPos = Math.min(firstParamPos, firstParamPathPos);
567
- let tmpCommand = fullcommand.substr(0, firstPos);
568
- const tmpParams = fullcommand.substr(firstPos);
569
- const lastSlashPos = tmpCommand.lastIndexOf('/');
570
- if (lastSlashPos >= 0) {
571
- cmdPath = tmpCommand.substr(0, lastSlashPos);
572
- tmpCommand = tmpCommand.substr(lastSlashPos + 1);
573
- }
574
-
575
- if (firstPos === 10000 && tmpCommand.indexOf(' ') > -1) {
576
- const parts = tmpCommand.split(' ');
577
- if (fs.existsSync(path.join(cmdPath, parts[0]))) {
578
- command = parts.shift();
579
- params = (parts.join(' ') + ' ' + tmpParams).trim();
580
- } else {
581
- command = tmpCommand.trim();
582
- params = tmpParams.trim();
583
- }
584
- } else {
585
- command = tmpCommand.trim();
586
- params = tmpParams.trim();
587
- }
588
- }
589
-
590
- return ({
591
- pid: pid,
592
- parentPid: ppid,
593
- name: _linux ? getName(command) : command,
594
- cpu: cpu,
595
- cpuu: 0,
596
- cpus: 0,
597
- mem: mem,
598
- priority: priority,
599
- memVsz: vsz,
600
- memRss: rss,
601
- nice: nice,
602
- started: started,
603
- state: state,
604
- tty: tty,
605
- user: user,
606
- command: command,
607
- params: params,
608
- path: cmdPath
609
- });
610
- }
611
-
612
- function parseProcesses(lines) {
613
- let result = [];
614
- if (lines.length > 1) {
615
- let head = lines[0];
616
- parsedhead = util.parseHead(head, 8);
617
- lines.shift();
618
- lines.forEach(function (line) {
619
- if (line.trim() !== '') {
620
- result.push(parseLine(line));
621
- }
622
- });
623
- }
624
- return result;
625
- }
626
- function parseProcesses2(lines) {
627
-
628
- function formatDateTime(time) {
629
- const month = ('0' + (time.getMonth() + 1).toString()).substr(-2);
630
- const year = time.getFullYear().toString();
631
- const day = ('0' + time.getDay().toString()).substr(-2);
632
- const hours = time.getHours().toString();
633
- const mins = time.getMinutes().toString();
634
- const secs = ('0' + time.getSeconds().toString()).substr(-2);
635
-
636
- return (year + '-' + month + '-' + day + ' ' + hours + ':' + mins + ':' + secs);
637
- }
638
-
639
- let result = [];
640
- lines.forEach(function (line) {
641
- if (line.trim() !== '') {
642
- line = line.trim().replace(/ +/g, ' ').replace(/,+/g, '.');
643
- const parts = line.split(' ');
644
- const command = parts.slice(9).join(' ');
645
- const pmem = parseFloat((1.0 * parseInt(parts[3]) * 1024 / os.totalmem()).toFixed(1));
646
- const elapsed_parts = parts[5].split(':');
647
- const started = formatDateTime(new Date(Date.now() - (elapsed_parts.length > 1 ? (elapsed_parts[0] * 60 + elapsed_parts[1]) * 1000 : elapsed_parts[0] * 1000)));
648
-
649
- result.push({
650
- pid: parseInt(parts[0]),
651
- parentPid: parseInt(parts[1]),
652
- name: getName(command),
653
- cpu: 0,
654
- cpuu: 0,
655
- cpus: 0,
656
- mem: pmem,
657
- priority: 0,
658
- memVsz: parseInt(parts[2]),
659
- memRss: parseInt(parts[3]),
660
- nice: parseInt(parts[4]),
661
- started: started,
662
- state: (parts[6] === 'R' ? 'running' : (parts[6] === 'S' ? 'sleeping' : (parts[6] === 'T' ? 'stopped' : (parts[6] === 'W' ? 'paging' : (parts[6] === 'X' ? 'dead' : (parts[6] === 'Z' ? 'zombie' : ((parts[6] === 'D' || parts[6] === 'U') ? 'blocked' : 'unknown'))))))),
663
- tty: parts[7],
664
- user: parts[8],
665
- command: command
666
- });
667
- }
668
- });
669
- return result;
670
- }
671
-
672
- return new Promise((resolve) => {
673
- process.nextTick(() => {
674
- let result = {
675
- all: 0,
676
- running: 0,
677
- blocked: 0,
678
- sleeping: 0,
679
- unknown: 0,
680
- list: []
681
- };
682
-
683
- let cmd = '';
684
-
685
- if ((_processes_cpu.ms && Date.now() - _processes_cpu.ms >= 500) || _processes_cpu.ms === 0) {
686
- if (_linux || _freebsd || _openbsd || _netbsd || _darwin || _sunos) {
687
- if (_linux) { cmd = 'export LC_ALL=C; ps -axo pid:11,ppid:11,pcpu:6,pmem:6,pri:5,vsz:11,rss:11,ni:5,lstart:30,state:5,tty:15,user:20,command; unset LC_ALL'; }
688
- if (_freebsd || _openbsd || _netbsd) { cmd = 'export LC_ALL=C; ps -axo pid,ppid,pcpu,pmem,pri,vsz,rss,ni,lstart,state,tty,user,command; unset LC_ALL'; }
689
- if (_darwin) { cmd = 'ps -axo pid,ppid,pcpu,pmem,pri,vsz=xxx_fake_title,rss=fake_title2,nice,lstart,state,tty,user,command -r'; }
690
- if (_sunos) { cmd = 'ps -Ao pid,ppid,pcpu,pmem,pri,vsz,rss,nice,stime,s,tty,user,comm'; }
691
- exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
692
- if (!error && stdout.toString().trim()) {
693
- result.list = (parseProcesses(stdout.toString().split('\n'))).slice();
694
- result.all = result.list.length;
695
- result.running = result.list.filter(function (e) {
696
- return e.state === 'running';
697
- }).length;
698
- result.blocked = result.list.filter(function (e) {
699
- return e.state === 'blocked';
700
- }).length;
701
- result.sleeping = result.list.filter(function (e) {
702
- return e.state === 'sleeping';
703
- }).length;
704
-
705
- if (_linux) {
706
- // calc process_cpu - ps is not accurate in linux!
707
- cmd = 'cat /proc/stat | grep "cpu "';
708
- for (let i = 0; i < result.list.length; i++) {
709
- cmd += (';cat /proc/' + result.list[i].pid + '/stat');
710
- }
711
- exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
712
- let curr_processes = stdout.toString().split('\n');
713
-
714
- // first line (all - /proc/stat)
715
- let all = parseProcStat(curr_processes.shift());
716
-
717
- // process
718
- let list_new = {};
719
- let resultProcess = {};
720
- for (let i = 0; i < curr_processes.length; i++) {
721
- resultProcess = calcProcStatLinux(curr_processes[i], all, _processes_cpu);
722
-
723
- if (resultProcess.pid) {
724
-
725
- // store pcpu in outer array
726
- let listPos = result.list.map(function (e) { return e.pid; }).indexOf(resultProcess.pid);
727
- if (listPos >= 0) {
728
- result.list[listPos].cpu = resultProcess.cpuu + resultProcess.cpus;
729
- result.list[listPos].cpuu = resultProcess.cpuu;
730
- result.list[listPos].cpus = resultProcess.cpus;
731
- }
732
-
733
- // save new values
734
- list_new[resultProcess.pid] = {
735
- cpuu: resultProcess.cpuu,
736
- cpus: resultProcess.cpus,
737
- utime: resultProcess.utime,
738
- stime: resultProcess.stime,
739
- cutime: resultProcess.cutime,
740
- cstime: resultProcess.cstime
741
- };
742
- }
743
- }
744
-
745
- // store old values
746
- _processes_cpu.all = all;
747
- // _processes_cpu.list = list_new;
748
- _processes_cpu.list = Object.assign({}, list_new);
749
- _processes_cpu.ms = Date.now() - _processes_cpu.ms;
750
- // _processes_cpu.result = result;
751
- _processes_cpu.result = Object.assign({}, result);
752
- if (callback) { callback(result); }
753
- resolve(result);
754
- });
755
- } else {
756
- if (callback) { callback(result); }
757
- resolve(result);
758
- }
759
- } else {
760
- cmd = 'ps -o pid,ppid,vsz,rss,nice,etime,stat,tty,user,comm';
761
- if (_sunos) {
762
- cmd = 'ps -o pid,ppid,vsz,rss,nice,etime,s,tty,user,comm';
763
- }
764
- exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
765
- if (!error) {
766
- let lines = stdout.toString().split('\n');
767
- lines.shift();
768
-
769
- result.list = parseProcesses2(lines).slice();
770
- result.all = result.list.length;
771
- result.running = result.list.filter(function (e) {
772
- return e.state === 'running';
773
- }).length;
774
- result.blocked = result.list.filter(function (e) {
775
- return e.state === 'blocked';
776
- }).length;
777
- result.sleeping = result.list.filter(function (e) {
778
- return e.state === 'sleeping';
779
- }).length;
780
- if (callback) { callback(result); }
781
- resolve(result);
782
- } else {
783
- if (callback) { callback(result); }
784
- resolve(result);
785
- }
786
- });
787
- }
788
- });
789
- } else if (_windows) {
790
- try {
791
- util.wmic('process get /value').then((stdout, error) => {
792
- if (!error) {
793
- let processSections = stdout.split(/\n\s*\n/);
794
- let procs = [];
795
- let procStats = [];
796
- let list_new = {};
797
- let allcpuu = _processes_cpu.all_utime;
798
- let allcpus = _processes_cpu.all_stime;
799
- for (let i = 0; i < processSections.length; i++) {
800
- if (processSections[i].trim() !== '') {
801
- let lines = processSections[i].trim().split('\r\n');
802
- let pid = parseInt(util.getValue(lines, 'ProcessId', '=', true), 10);
803
- let parentPid = parseInt(util.getValue(lines, 'ParentProcessId', '=', true), 10);
804
- let statusValue = util.getValue(lines, 'ExecutionState', '=');
805
- let name = util.getValue(lines, 'Caption', '=', true);
806
- let commandLine = util.getValue(lines, 'CommandLine', '=', true);
807
- let commandPath = util.getValue(lines, 'ExecutablePath', '=', true);
808
- let utime = parseInt(util.getValue(lines, 'UserModeTime', '=', true), 10);
809
- let stime = parseInt(util.getValue(lines, 'KernelModeTime', '=', true), 10);
810
- let memw = parseInt(util.getValue(lines, 'WorkingSetSize', '=', true), 10);
811
- allcpuu = allcpuu + utime;
812
- allcpus = allcpus + stime;
813
- result.all++;
814
- if (!statusValue) { result.unknown++; }
815
- if (statusValue === '3') { result.running++; }
816
- if (statusValue === '4' || statusValue === '5') { result.blocked++; }
817
-
818
- procStats.push({
819
- pid: pid,
820
- utime: utime,
821
- stime: stime,
822
- cpu: 0,
823
- cpuu: 0,
824
- cpus: 0,
825
- });
826
- procs.push({
827
- pid: pid,
828
- parentPid: parentPid,
829
- name: name,
830
- cpu: 0,
831
- cpuu: 0,
832
- cpus: 0,
833
- mem: memw / os.totalmem() * 100,
834
- priority: parseInt(util.getValue(lines, 'Priority', '=', true), 10),
835
- memVsz: parseInt(util.getValue(lines, 'PageFileUsage', '=', true), 10),
836
- memRss: Math.floor(parseInt(util.getValue(lines, 'WorkingSetSize', '=', true), 10) / 1024),
837
- nice: 0,
838
- started: parseTimeWin(util.getValue(lines, 'CreationDate', '=', true)),
839
- state: (!statusValue ? _winStatusValues[0] : _winStatusValues[statusValue]),
840
- tty: '',
841
- user: '',
842
- command: commandLine || name,
843
- path: commandPath,
844
- params: ''
845
- });
846
- }
847
- }
848
- result.sleeping = result.all - result.running - result.blocked - result.unknown;
849
- result.list = procs;
850
- for (let i = 0; i < procStats.length; i++) {
851
- let resultProcess = calcProcStatWin(procStats[i], allcpuu + allcpus, _processes_cpu);
852
-
853
- // store pcpu in outer array
854
- let listPos = result.list.map(function (e) { return e.pid; }).indexOf(resultProcess.pid);
855
- if (listPos >= 0) {
856
- result.list[listPos].cpu = resultProcess.cpuu + resultProcess.cpus;
857
- result.list[listPos].cpuu = resultProcess.cpuu;
858
- result.list[listPos].cpus = resultProcess.cpus;
859
- }
860
-
861
- // save new values
862
- list_new[resultProcess.pid] = {
863
- cpuu: resultProcess.cpuu,
864
- cpus: resultProcess.cpus,
865
- utime: resultProcess.utime,
866
- stime: resultProcess.stime
867
- };
868
- }
869
- // store old values
870
- _processes_cpu.all = allcpuu + allcpus;
871
- _processes_cpu.all_utime = allcpuu;
872
- _processes_cpu.all_stime = allcpus;
873
- // _processes_cpu.list = list_new;
874
- _processes_cpu.list = Object.assign({}, list_new);
875
- _processes_cpu.ms = Date.now() - _processes_cpu.ms;
876
- // _processes_cpu.result = result;
877
- _processes_cpu.result = Object.assign({}, result);
878
- }
879
- if (callback) {
880
- callback(result);
881
- }
882
- resolve(result);
883
- });
884
- } catch (e) {
885
- if (callback) { callback(result); }
886
- resolve(result);
887
- }
888
- } else {
889
- if (callback) { callback(result); }
890
- resolve(result);
891
- }
892
- } else {
893
- if (callback) { callback(_processes_cpu.result); }
894
- resolve(_processes_cpu.result);
895
- }
896
- });
897
- });
898
- }
899
-
900
- exports.processes = processes;
901
-
902
- // --------------------------
903
- // PS - process load
904
- // get detailed information about a certain process
905
- // (PID, CPU-Usage %, Mem-Usage %)
906
-
907
- function processLoad(proc, callback) {
908
-
909
- // fallback - if only callback is given
910
- if (util.isFunction(proc) && !callback) {
911
- callback = proc;
912
- proc = '';
913
- }
914
-
915
- return new Promise((resolve) => {
916
- process.nextTick(() => {
917
-
918
- proc = proc || '';
919
-
920
- if (typeof proc !== 'string') {
921
- if (callback) { callback([]); }
922
- return resolve([]);
923
- }
924
-
925
- let processesString = '';
926
- processesString.__proto__.toLowerCase = util.stringToLower;
927
- processesString.__proto__.replace = util.stringReplace;
928
- processesString.__proto__.trim = util.stringTrim;
929
-
930
- const s = util.sanitizeShellString(proc);
931
- for (let i = 0; i <= util.mathMin(s.length, 2000); i++) {
932
- if (!(s[i] === undefined)) {
933
- processesString = processesString + s[i];
934
- }
935
- }
936
-
937
- processesString = processesString.trim().toLowerCase().replace(/, /g, '|').replace(/,+/g, '|');
938
- if (processesString === '') {
939
- processesString = '*';
940
- }
941
- if (util.isPrototypePolluted() && processesString !== '*') {
942
- processesString = '------';
943
- }
944
- let processes = processesString.split('|');
945
- let result = [];
946
-
947
- const procSanitized = util.isPrototypePolluted() ? '' : util.sanitizeShellString(proc);
948
-
949
- // from here new
950
- // let result = {
951
- // 'proc': procSanitized,
952
- // 'pid': null,
953
- // 'cpu': 0,
954
- // 'mem': 0
955
- // };
956
- if (procSanitized && processes.length && processes[0] !== '------') {
957
- if (_windows) {
958
- try {
959
- util.wmic('process get /value').then((stdout, error) => {
960
- if (!error) {
961
- let processSections = stdout.split(/\n\s*\n/);
962
- let procStats = [];
963
- let list_new = {};
964
- let allcpuu = _process_cpu.all_utime;
965
- let allcpus = _process_cpu.all_stime;
966
-
967
- // go through all processes
968
- for (let i = 0; i < processSections.length; i++) {
969
- if (processSections[i].trim() !== '') {
970
- let lines = processSections[i].trim().split('\r\n');
971
- let pid = parseInt(util.getValue(lines, 'ProcessId', '=', true), 10);
972
- let name = util.getValue(lines, 'Caption', '=', true);
973
- let utime = parseInt(util.getValue(lines, 'UserModeTime', '=', true), 10);
974
- let stime = parseInt(util.getValue(lines, 'KernelModeTime', '=', true), 10);
975
- let mem = parseInt(util.getValue(lines, 'WorkingSetSize', '=', true), 10);
976
- allcpuu = allcpuu + utime;
977
- allcpus = allcpus + stime;
978
-
979
- procStats.push({
980
- pid: pid,
981
- name,
982
- utime: utime,
983
- stime: stime,
984
- cpu: 0,
985
- cpuu: 0,
986
- cpus: 0,
987
- mem
988
- });
989
- let pname = '';
990
- let inList = false;
991
- processes.forEach(function (proc) {
992
- // console.log(proc)
993
- // console.log(item)
994
- // inList = inList || item.name.toLowerCase() === proc.toLowerCase();
995
- if (name.toLowerCase().indexOf(proc.toLowerCase()) >= 0 && !inList) {
996
- inList = true;
997
- pname = proc;
998
- }
999
- });
1000
-
1001
- if (processesString === '*' || inList) {
1002
- let processFound = false;
1003
- result.forEach(function (item) {
1004
- if (item.proc.toLowerCase() === pname.toLowerCase()) {
1005
- item.pids.push(pid);
1006
- item.mem += mem / os.totalmem() * 100;
1007
- processFound = true;
1008
- }
1009
- });
1010
- if (!processFound) {
1011
- result.push({
1012
- proc: pname,
1013
- pid: pid,
1014
- pids: [pid],
1015
- cpu: 0,
1016
- mem: mem / os.totalmem() * 100
1017
- });
1018
- }
1019
- }
1020
- }
1021
- }
1022
- // add missing processes
1023
- if (processesString !== '*') {
1024
- let processesMissing = processes.filter(function (name) {
1025
- // return procStats.filter(function(item) { return item.name.toLowerCase() === name }).length === 0;
1026
- return procStats.filter(function (item) { return item.name.toLowerCase().indexOf(name) >= 0; }).length === 0;
1027
-
1028
- });
1029
- processesMissing.forEach(function (procName) {
1030
- result.push({
1031
- proc: procName,
1032
- pid: null,
1033
- pids: [],
1034
- cpu: 0,
1035
- mem: 0
1036
- });
1037
- });
1038
- }
1039
-
1040
- // calculate proc stats for each proc
1041
- for (let i = 0; i < procStats.length; i++) {
1042
- let resultProcess = calcProcStatWin(procStats[i], allcpuu + allcpus, _process_cpu);
1043
-
1044
- let listPos = -1;
1045
- for (let j = 0; j < result.length; j++) {
1046
- if (result[j].pid === resultProcess.pid || result[j].pids.indexOf(resultProcess.pid) >= 0) { listPos = j; }
1047
- }
1048
- if (listPos >= 0) {
1049
- result[listPos].cpu += resultProcess.cpuu + resultProcess.cpus;
1050
- }
1051
-
1052
- // save new values
1053
- list_new[resultProcess.pid] = {
1054
- cpuu: resultProcess.cpuu,
1055
- cpus: resultProcess.cpus,
1056
- utime: resultProcess.utime,
1057
- stime: resultProcess.stime
1058
- };
1059
- }
1060
- // store old values
1061
- _process_cpu.all = allcpuu + allcpus;
1062
- _process_cpu.all_utime = allcpuu;
1063
- _process_cpu.all_stime = allcpus;
1064
- // _process_cpu.list = list_new;
1065
- _process_cpu.list = Object.assign({}, list_new);
1066
- _process_cpu.ms = Date.now() - _process_cpu.ms;
1067
- _process_cpu.result = JSON.parse(JSON.stringify(result));
1068
- if (callback) {
1069
- callback(result);
1070
- }
1071
- resolve(result);
1072
- }
1073
- });
1074
- } catch (e) {
1075
- if (callback) { callback(result); }
1076
- resolve(result);
1077
- }
1078
- }
1079
-
1080
- if (_darwin || _linux || _freebsd || _openbsd || _netbsd) {
1081
- const params = ['-axo', 'pid,pcpu,pmem,comm'];
1082
- util.execSafe('ps', params).then((stdout) => {
1083
- if (stdout) {
1084
- let procStats = [];
1085
- let lines = stdout.toString().split('\n').filter(function (line) {
1086
- if (processesString === '*') { return true; }
1087
- if (line.toLowerCase().indexOf('grep') !== -1) { return false; } // remove this??
1088
- let found = false;
1089
- processes.forEach(function (item) {
1090
- found = found || (line.toLowerCase().indexOf(item.toLowerCase()) >= 0);
1091
- });
1092
- return found;
1093
- });
1094
-
1095
- lines.forEach(function (line) {
1096
- let data = line.trim().replace(/ +/g, ' ').split(' ');
1097
- if (data.length > 3) {
1098
- procStats.push({
1099
- name: data[3].substring(data[3].lastIndexOf('/') + 1),
1100
- pid: parseInt(data[0]) || 0,
1101
- cpu: parseFloat(data[1].replace(',', '.')),
1102
- mem: parseFloat(data[2].replace(',', '.'))
1103
- });
1104
- }
1105
- });
1106
-
1107
- procStats.forEach(function (item) {
1108
- let listPos = -1;
1109
- let inList = false;
1110
- let name = '';
1111
- for (let j = 0; j < result.length; j++) {
1112
- // if (result[j].proc.toLowerCase() === item.name.toLowerCase()) {
1113
- // if (result[j].proc.toLowerCase().indexOf(item.name.toLowerCase()) >= 0) {
1114
- if (item.name.toLowerCase().indexOf(result[j].proc.toLowerCase()) >= 0) {
1115
- listPos = j;
1116
- }
1117
- }
1118
- // console.log(listPos);
1119
- processes.forEach(function (proc) {
1120
- // console.log(proc)
1121
- // console.log(item)
1122
- // inList = inList || item.name.toLowerCase() === proc.toLowerCase();
1123
- if (item.name.toLowerCase().indexOf(proc.toLowerCase()) >= 0 && !inList) {
1124
- inList = true;
1125
- name = proc;
1126
- }
1127
- });
1128
- // console.log(item);
1129
- // console.log(listPos);
1130
- if ((processesString === '*') || inList) {
1131
- if (listPos < 0) {
1132
- result.push({
1133
- proc: name,
1134
- pid: item.pid,
1135
- pids: [item.pid],
1136
- cpu: item.cpu,
1137
- mem: item.mem
1138
- });
1139
- } else {
1140
- result[listPos].pids.push(item.pid);
1141
- result[listPos].cpu += item.cpu;
1142
- result[listPos].mem += item.mem;
1143
- }
1144
- }
1145
- });
1146
-
1147
- if (processesString !== '*') {
1148
- // add missing processes
1149
- let processesMissing = processes.filter(function (name) {
1150
- return procStats.filter(function (item) { return item.name.toLowerCase().indexOf(name) >= 0; }).length === 0;
1151
- });
1152
- processesMissing.forEach(function (procName) {
1153
- result.push({
1154
- proc: procName,
1155
- pid: null,
1156
- pids: [],
1157
- cpu: 0,
1158
- mem: 0
1159
- });
1160
- });
1161
- }
1162
- if (_linux) {
1163
- // calc process_cpu - ps is not accurate in linux!
1164
- result.forEach(function (item) {
1165
- item.cpu = 0;
1166
- });
1167
- let cmd = 'cat /proc/stat | grep "cpu "';
1168
- for (let i in result) {
1169
- for (let j in result[i].pids) {
1170
- cmd += (';cat /proc/' + result[i].pids[j] + '/stat');
1171
- }
1172
- }
1173
- exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
1174
- let curr_processes = stdout.toString().split('\n');
1175
-
1176
- // first line (all - /proc/stat)
1177
- let all = parseProcStat(curr_processes.shift());
1178
-
1179
- // process
1180
- let list_new = {};
1181
- let resultProcess = {};
1182
-
1183
- for (let i = 0; i < curr_processes.length; i++) {
1184
- resultProcess = calcProcStatLinux(curr_processes[i], all, _process_cpu);
1185
-
1186
- if (resultProcess.pid) {
1187
-
1188
- // find result item
1189
- let resultItemId = -1;
1190
- for (let i in result) {
1191
- if (result[i].pids.indexOf(resultProcess.pid) >= 0) {
1192
- resultItemId = i;
1193
- }
1194
- }
1195
- // store pcpu in outer result
1196
- if (resultItemId >= 0) {
1197
- result[resultItemId].cpu += resultProcess.cpuu + resultProcess.cpus;
1198
- }
1199
-
1200
- // save new values
1201
- list_new[resultProcess.pid] = {
1202
- cpuu: resultProcess.cpuu,
1203
- cpus: resultProcess.cpus,
1204
- utime: resultProcess.utime,
1205
- stime: resultProcess.stime,
1206
- cutime: resultProcess.cutime,
1207
- cstime: resultProcess.cstime
1208
- };
1209
- }
1210
- }
1211
-
1212
- result.forEach(function (item) {
1213
- item.cpu = Math.round(item.cpu * 100) / 100;
1214
- });
1215
-
1216
- _process_cpu.all = all;
1217
- // _process_cpu.list = list_new;
1218
- _process_cpu.list = Object.assign({}, list_new);
1219
- _process_cpu.ms = Date.now() - _process_cpu.ms;
1220
- // _process_cpu.result = result;
1221
- _process_cpu.result = Object.assign({}, result);
1222
- if (callback) { callback(result); }
1223
- resolve(result);
1224
- });
1225
- } else {
1226
- if (callback) { callback(result); }
1227
- resolve(result);
1228
- }
1229
- } else {
1230
- if (callback) { callback(result); }
1231
- resolve(result);
1232
- }
1233
- });
1234
- }
1235
- }
1236
- });
1237
- });
1238
- }
1239
-
1240
- exports.processLoad = processLoad;
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // processes.js
5
+ // ----------------------------------------------------------------------------------
6
+ // Description: System Information - library
7
+ // for Node.js
8
+ // Copyright: (c) 2014 - 2021
9
+ // Author: Sebastian Hildebrandt
10
+ // ----------------------------------------------------------------------------------
11
+ // License: MIT
12
+ // ==================================================================================
13
+ // 10. Processes
14
+ // ----------------------------------------------------------------------------------
15
+
16
+ const os = require('os');
17
+ const fs = require('fs');
18
+ const path = require('path');
19
+ const exec = require('child_process').exec;
20
+ const execSync = require('child_process').execSync;
21
+
22
+ const util = require('./util');
23
+
24
+ let _platform = process.platform;
25
+
26
+ const _linux = (_platform === 'linux');
27
+ const _darwin = (_platform === 'darwin');
28
+ const _windows = (_platform === 'win32');
29
+ const _freebsd = (_platform === 'freebsd');
30
+ const _openbsd = (_platform === 'openbsd');
31
+ const _netbsd = (_platform === 'netbsd');
32
+ const _sunos = (_platform === 'sunos');
33
+
34
+ const _processes_cpu = {
35
+ all: 0,
36
+ all_utime: 0,
37
+ all_stime: 0,
38
+ list: {},
39
+ ms: 0,
40
+ result: {}
41
+ };
42
+ const _services_cpu = {
43
+ all: 0,
44
+ all_utime: 0,
45
+ all_stime: 0,
46
+ list: {},
47
+ ms: 0,
48
+ result: {}
49
+ };
50
+ const _process_cpu = {
51
+ all: 0,
52
+ all_utime: 0,
53
+ all_stime: 0,
54
+ list: {},
55
+ ms: 0,
56
+ result: {}
57
+ };
58
+
59
+ const _winStatusValues = {
60
+ '0': 'unknown',
61
+ '1': 'other',
62
+ '2': 'ready',
63
+ '3': 'running',
64
+ '4': 'blocked',
65
+ '5': 'suspended blocked',
66
+ '6': 'suspended ready',
67
+ '7': 'terminated',
68
+ '8': 'stopped',
69
+ '9': 'growing',
70
+ };
71
+
72
+
73
+ function parseTimeWin(time) {
74
+ time = time || '';
75
+ if (time) {
76
+ return (time.substr(0, 4) + '-' + time.substr(4, 2) + '-' + time.substr(6, 2) + ' ' + time.substr(8, 2) + ':' + time.substr(10, 2) + ':' + time.substr(12, 2));
77
+ } else {
78
+ return '';
79
+ }
80
+ }
81
+
82
+ function parseTimeUnix(time) {
83
+ let result = time;
84
+ let parts = time.replace(/ +/g, ' ').split(' ');
85
+ if (parts.length === 5) {
86
+ result = parts[4] + '-' + ('0' + ('JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.indexOf(parts[1].toUpperCase()) / 3 + 1)).slice(-2) + '-' + ('0' + parts[2]).slice(-2) + ' ' + parts[3];
87
+ }
88
+ return result;
89
+ }
90
+
91
+ // --------------------------
92
+ // PS - services
93
+ // pass a comma separated string with services to check (mysql, apache, postgresql, ...)
94
+ // this function gives an array back, if the services are running.
95
+
96
+ function services(srv, callback) {
97
+
98
+ // fallback - if only callback is given
99
+ if (util.isFunction(srv) && !callback) {
100
+ callback = srv;
101
+ srv = '';
102
+ }
103
+
104
+ return new Promise((resolve) => {
105
+ process.nextTick(() => {
106
+ if (typeof srv !== 'string') {
107
+ if (callback) { callback([]); }
108
+ return resolve([]);
109
+ }
110
+
111
+ if (srv) {
112
+ let srvString = '';
113
+ srvString.__proto__.toLowerCase = util.stringToLower;
114
+ srvString.__proto__.replace = util.stringReplace;
115
+ srvString.__proto__.trim = util.stringTrim;
116
+
117
+ const s = util.sanitizeShellString(srv);
118
+ for (let i = 0; i <= util.mathMin(s.length, 2000); i++) {
119
+ if (!(s[i] === undefined)) {
120
+ srvString = srvString + s[i];
121
+ }
122
+ }
123
+
124
+ srvString = srvString.trim().toLowerCase().replace(/, /g, '|').replace(/,+/g, '|');
125
+ if (srvString === '') {
126
+ srvString = '*';
127
+ }
128
+ if (util.isPrototypePolluted() && srvString !== '*') {
129
+ srvString = '------';
130
+ }
131
+ let srvs = srvString.split('|');
132
+ let result = [];
133
+ let dataSrv = [];
134
+ // let allSrv = [];
135
+
136
+ if (_linux || _freebsd || _openbsd || _netbsd || _darwin) {
137
+ if ((_linux || _freebsd || _openbsd || _netbsd) && srvString === '*') {
138
+ try {
139
+ const tmpsrv = execSync('systemctl --type=service --no-legend 2> /dev/null').toString().split('\n');
140
+ srvs = [];
141
+ for (const s of tmpsrv) {
142
+ const name = s.split('.service')[0];
143
+ if (name) {
144
+ srvs.push(name);
145
+ }
146
+ }
147
+ srvString = srvs.join('|');
148
+ } catch (d) {
149
+ try {
150
+ srvString = '';
151
+ const tmpsrv = execSync('service --status-all 2> /dev/null').toString().split('\n');
152
+ for (const s of tmpsrv) {
153
+ const parts = s.split(']');
154
+ if (parts.length === 2) {
155
+ srvString += (srvString !== '' ? '|' : '') + parts[1].trim();
156
+ // allSrv.push({ name: parts[1].trim(), running: parts[0].indexOf('+') > 0 });
157
+ }
158
+ }
159
+ srvs = srvString.split('|');
160
+ } catch (e) {
161
+ try {
162
+ const srvStr = execSync('ls /etc/init.d/ -m 2> /dev/null').toString().split('\n').join('');
163
+ srvString = '';
164
+ if (srvStr) {
165
+ const tmpsrv = srvStr.split(',');
166
+ for (const s of tmpsrv) {
167
+ const name = s.trim();
168
+ if (name) {
169
+ srvString += (srvString !== '' ? '|' : '') + name;
170
+ // allSrv.push({ name: name, running: null });
171
+ }
172
+ }
173
+ srvs = srvString.split('|');
174
+ }
175
+ } catch (f) {
176
+ // allSrv = [];
177
+ srvString = '';
178
+ srvs = [];
179
+ }
180
+ }
181
+ }
182
+ }
183
+ if ((_darwin) && srvString === '*') { // service enumeration not yet suported on mac OS
184
+ if (callback) { callback(result); }
185
+ resolve(result);
186
+ }
187
+ let args = (_darwin) ? ['-caxo', 'pcpu,pmem,pid,command'] : ['-axo', 'pcpu,pmem,pid,command'];
188
+ if (srvString !== '' && srvs.length > 0) {
189
+ util.execSafe('ps', args).then((stdout) => {
190
+ if (stdout) {
191
+ let lines = stdout.replace(/ +/g, ' ').replace(/,+/g, '.').split('\n');
192
+ srvs.forEach(function (srv) {
193
+ let ps;
194
+ if (_darwin) {
195
+ ps = lines.filter(function (e) {
196
+ return (e.toLowerCase().indexOf(srv) !== -1);
197
+ });
198
+
199
+ } else {
200
+ ps = lines.filter(function (e) {
201
+ return (e.toLowerCase().indexOf(' ' + srv + ':') !== -1) || (e.toLowerCase().indexOf('/' + srv) !== -1);
202
+ });
203
+ }
204
+ // let singleSrv = allSrv.filter(item => { return item.name === srv; });
205
+ const pids = [];
206
+ for (const p of ps) {
207
+ const pid = p.trim().split(' ')[2];
208
+ if (pid) {
209
+ pids.push(parseInt(pid, 10));
210
+ }
211
+ }
212
+ result.push({
213
+ name: srv,
214
+ // running: (allSrv.length && singleSrv.length && singleSrv[0].running !== null ? singleSrv[0].running : ps.length > 0),
215
+ running: ps.length > 0,
216
+ startmode: '',
217
+ pids: pids,
218
+ cpu: parseFloat((ps.reduce(function (pv, cv) {
219
+ return pv + parseFloat(cv.trim().split(' ')[0]);
220
+ }, 0)).toFixed(2)),
221
+ mem: parseFloat((ps.reduce(function (pv, cv) {
222
+ return pv + parseFloat(cv.trim().split(' ')[1]);
223
+ }, 0)).toFixed(2))
224
+ });
225
+ });
226
+ if (_linux) {
227
+ // calc process_cpu - ps is not accurate in linux!
228
+ let cmd = 'cat /proc/stat | grep "cpu "';
229
+ for (let i in result) {
230
+ for (let j in result[i].pids) {
231
+ cmd += (';cat /proc/' + result[i].pids[j] + '/stat');
232
+ }
233
+ }
234
+ exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
235
+ let curr_processes = stdout.toString().split('\n');
236
+
237
+ // first line (all - /proc/stat)
238
+ let all = parseProcStat(curr_processes.shift());
239
+
240
+ // process
241
+ let list_new = {};
242
+ let resultProcess = {};
243
+ for (let i = 0; i < curr_processes.length; i++) {
244
+ resultProcess = calcProcStatLinux(curr_processes[i], all, _services_cpu);
245
+
246
+ if (resultProcess.pid) {
247
+ let listPos = -1;
248
+ for (let i in result) {
249
+ for (let j in result[i].pids) {
250
+ if (parseInt(result[i].pids[j]) === parseInt(resultProcess.pid)) {
251
+ listPos = i;
252
+ }
253
+ }
254
+ }
255
+ if (listPos >= 0) {
256
+ result[listPos].cpu += resultProcess.cpuu + resultProcess.cpus;
257
+ }
258
+
259
+ // save new values
260
+ list_new[resultProcess.pid] = {
261
+ cpuu: resultProcess.cpuu,
262
+ cpus: resultProcess.cpus,
263
+ utime: resultProcess.utime,
264
+ stime: resultProcess.stime,
265
+ cutime: resultProcess.cutime,
266
+ cstime: resultProcess.cstime
267
+ };
268
+ }
269
+ }
270
+
271
+ // store old values
272
+ _services_cpu.all = all;
273
+ // _services_cpu.list = list_new;
274
+ _services_cpu.list = Object.assign({}, list_new);
275
+ _services_cpu.ms = Date.now() - _services_cpu.ms;
276
+ // _services_cpu.result = result;
277
+ _services_cpu.result = Object.assign({}, result);
278
+ if (callback) { callback(result); }
279
+ resolve(result);
280
+ });
281
+ } else {
282
+ if (callback) { callback(result); }
283
+ resolve(result);
284
+ }
285
+ } else {
286
+ args = ['-o', 'comm'];
287
+ util.execSafe('ps', args).then((stdout) => {
288
+ if (stdout) {
289
+ let lines = stdout.replace(/ +/g, ' ').replace(/,+/g, '.').split('\n');
290
+ srvs.forEach(function (srv) {
291
+ let ps = lines.filter(function (e) {
292
+ return e.indexOf(srv) !== -1;
293
+ });
294
+ result.push({
295
+ name: srv,
296
+ running: ps.length > 0,
297
+ startmode: '',
298
+ cpu: 0,
299
+ mem: 0
300
+ });
301
+ });
302
+ if (callback) { callback(result); }
303
+ resolve(result);
304
+ } else {
305
+ srvs.forEach(function (srv) {
306
+ result.push({
307
+ name: srv,
308
+ running: false,
309
+ startmode: '',
310
+ cpu: 0,
311
+ mem: 0
312
+ });
313
+ });
314
+ if (callback) { callback(result); }
315
+ resolve(result);
316
+ }
317
+ });
318
+ }
319
+ });
320
+ } else {
321
+ if (callback) { callback(result); }
322
+ resolve(result);
323
+ }
324
+ }
325
+ if (_windows) {
326
+ try {
327
+ util.powerShell('Get-WmiObject Win32_Service | fl *').then((stdout, error) => {
328
+ if (!error) {
329
+ let serviceSections = stdout.split(/\n\s*\n/);
330
+ for (let i = 0; i < serviceSections.length; i++) {
331
+ if (serviceSections[i].trim() !== '') {
332
+ let lines = serviceSections[i].trim().split('\r\n');
333
+ let srvName = util.getValue(lines, 'Name', ':', true).toLowerCase();
334
+ let srvCaption = util.getValue(lines, 'Caption', ':', true).toLowerCase();
335
+ let started = util.getValue(lines, 'Started', ':', true);
336
+ let startMode = util.getValue(lines, 'StartMode', ':', true);
337
+ let pid = util.getValue(lines, 'ProcessId', ':', true);
338
+ if (srvString === '*' || srvs.indexOf(srvName) >= 0 || srvs.indexOf(srvCaption) >= 0) {
339
+ result.push({
340
+ name: srvName,
341
+ running: (started === 'TRUE'),
342
+ startmode: startMode,
343
+ pids: [pid],
344
+ cpu: 0,
345
+ mem: 0
346
+ });
347
+ dataSrv.push(srvName);
348
+ dataSrv.push(srvCaption);
349
+ }
350
+ }
351
+ }
352
+ if (srvString !== '*') {
353
+ let srvsMissing = srvs.filter(function (e) {
354
+ return dataSrv.indexOf(e) === -1;
355
+ });
356
+ srvsMissing.forEach(function (srvName) {
357
+ result.push({
358
+ name: srvName,
359
+ running: false,
360
+ startmode: '',
361
+ pids: [],
362
+ cpu: 0,
363
+ mem: 0
364
+ });
365
+ });
366
+ }
367
+ if (callback) { callback(result); }
368
+ resolve(result);
369
+ } else {
370
+ srvs.forEach(function (srvName) {
371
+ result.push({
372
+ name: srvName,
373
+ running: false,
374
+ startmode: '',
375
+ cpu: 0,
376
+ mem: 0
377
+ });
378
+ });
379
+ if (callback) { callback(result); }
380
+ resolve(result);
381
+ }
382
+ });
383
+ } catch (e) {
384
+ if (callback) { callback(result); }
385
+ resolve(result);
386
+ }
387
+ }
388
+ } else {
389
+ if (callback) { callback([]); }
390
+ resolve([]);
391
+ }
392
+ });
393
+ });
394
+ }
395
+
396
+ exports.services = services;
397
+
398
+ function parseProcStat(line) {
399
+ let parts = line.replace(/ +/g, ' ').split(' ');
400
+ let user = (parts.length >= 2 ? parseInt(parts[1]) : 0);
401
+ let nice = (parts.length >= 3 ? parseInt(parts[2]) : 0);
402
+ let system = (parts.length >= 4 ? parseInt(parts[3]) : 0);
403
+ let idle = (parts.length >= 5 ? parseInt(parts[4]) : 0);
404
+ let iowait = (parts.length >= 6 ? parseInt(parts[5]) : 0);
405
+ let irq = (parts.length >= 7 ? parseInt(parts[6]) : 0);
406
+ let softirq = (parts.length >= 8 ? parseInt(parts[7]) : 0);
407
+ let steal = (parts.length >= 9 ? parseInt(parts[8]) : 0);
408
+ let guest = (parts.length >= 10 ? parseInt(parts[9]) : 0);
409
+ let guest_nice = (parts.length >= 11 ? parseInt(parts[10]) : 0);
410
+ return user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice;
411
+ }
412
+
413
+ function calcProcStatLinux(line, all, _cpu_old) {
414
+ let statparts = line.replace(/ +/g, ' ').split(')');
415
+ if (statparts.length >= 2) {
416
+ let parts = statparts[1].split(' ');
417
+ if (parts.length >= 16) {
418
+ let pid = parseInt(statparts[0].split(' ')[0]);
419
+ let utime = parseInt(parts[12]);
420
+ let stime = parseInt(parts[13]);
421
+ let cutime = parseInt(parts[14]);
422
+ let cstime = parseInt(parts[15]);
423
+
424
+ // calc
425
+ let cpuu = 0;
426
+ let cpus = 0;
427
+ if (_cpu_old.all > 0 && _cpu_old.list[pid]) {
428
+ cpuu = (utime + cutime - _cpu_old.list[pid].utime - _cpu_old.list[pid].cutime) / (all - _cpu_old.all) * 100; // user
429
+ cpus = (stime + cstime - _cpu_old.list[pid].stime - _cpu_old.list[pid].cstime) / (all - _cpu_old.all) * 100; // system
430
+ } else {
431
+ cpuu = (utime + cutime) / (all) * 100; // user
432
+ cpus = (stime + cstime) / (all) * 100; // system
433
+ }
434
+ return {
435
+ pid: pid,
436
+ utime: utime,
437
+ stime: stime,
438
+ cutime: cutime,
439
+ cstime: cstime,
440
+ cpuu: cpuu,
441
+ cpus: cpus
442
+ };
443
+ } else {
444
+ return {
445
+ pid: 0,
446
+ utime: 0,
447
+ stime: 0,
448
+ cutime: 0,
449
+ cstime: 0,
450
+ cpuu: 0,
451
+ cpus: 0
452
+ };
453
+ }
454
+ } else {
455
+ return {
456
+ pid: 0,
457
+ utime: 0,
458
+ stime: 0,
459
+ cutime: 0,
460
+ cstime: 0,
461
+ cpuu: 0,
462
+ cpus: 0
463
+ };
464
+ }
465
+ }
466
+
467
+ function calcProcStatWin(procStat, all, _cpu_old) {
468
+ // calc
469
+ let cpuu = 0;
470
+ let cpus = 0;
471
+ if (_cpu_old.all > 0 && _cpu_old.list[procStat.pid]) {
472
+ cpuu = (procStat.utime - _cpu_old.list[procStat.pid].utime) / (all - _cpu_old.all) * 100; // user
473
+ cpus = (procStat.stime - _cpu_old.list[procStat.pid].stime) / (all - _cpu_old.all) * 100; // system
474
+ } else {
475
+ cpuu = (procStat.utime) / (all) * 100; // user
476
+ cpus = (procStat.stime) / (all) * 100; // system
477
+ }
478
+ return {
479
+ pid: procStat.pid,
480
+ utime: cpuu > 0 ? procStat.utime : 0,
481
+ stime: cpus > 0 ? procStat.stime : 0,
482
+ cpuu: cpuu > 0 ? cpuu : 0,
483
+ cpus: cpus > 0 ? cpus : 0
484
+ };
485
+ }
486
+
487
+
488
+
489
+ // --------------------------
490
+ // running processes
491
+
492
+ function processes(callback) {
493
+
494
+ let parsedhead = [];
495
+
496
+ function getName(command) {
497
+ command = command || '';
498
+ let result = command.split(' ')[0];
499
+ if (result.substr(-1) === ':') {
500
+ result = result.substr(0, result.length - 1);
501
+ }
502
+ if (result.substr(0, 1) !== '[') {
503
+ let parts = result.split('/');
504
+ if (isNaN(parseInt(parts[parts.length - 1]))) {
505
+ result = parts[parts.length - 1];
506
+ } else {
507
+ result = parts[0];
508
+ }
509
+ }
510
+ return result;
511
+ }
512
+
513
+ function parseLine(line) {
514
+
515
+ let offset = 0;
516
+ let offset2 = 0;
517
+
518
+ function checkColumn(i) {
519
+ offset = offset2;
520
+ if (parsedhead[i]) {
521
+ offset2 = line.substring(parsedhead[i].to + offset, 10000).indexOf(' ');
522
+ } else {
523
+ offset2 = 10000;
524
+ }
525
+ }
526
+
527
+ checkColumn(0);
528
+ const pid = parseInt(line.substring(parsedhead[0].from + offset, parsedhead[0].to + offset2));
529
+ checkColumn(1);
530
+ const ppid = parseInt(line.substring(parsedhead[1].from + offset, parsedhead[1].to + offset2));
531
+ checkColumn(2);
532
+ const cpu = parseFloat(line.substring(parsedhead[2].from + offset, parsedhead[2].to + offset2).replace(/,/g, '.'));
533
+ checkColumn(3);
534
+ const mem = parseFloat(line.substring(parsedhead[3].from + offset, parsedhead[3].to + offset2).replace(/,/g, '.'));
535
+ checkColumn(4);
536
+ const priority = parseInt(line.substring(parsedhead[4].from + offset, parsedhead[4].to + offset2));
537
+ checkColumn(5);
538
+ const vsz = parseInt(line.substring(parsedhead[5].from + offset, parsedhead[5].to + offset2));
539
+ checkColumn(6);
540
+ const rss = parseInt(line.substring(parsedhead[6].from + offset, parsedhead[6].to + offset2));
541
+ checkColumn(7);
542
+ const nice = parseInt(line.substring(parsedhead[7].from + offset, parsedhead[7].to + offset2)) || 0;
543
+ checkColumn(8);
544
+ const started = parseTimeUnix(line.substring(parsedhead[8].from + offset, parsedhead[8].to + offset2).trim());
545
+ checkColumn(9);
546
+ let state = line.substring(parsedhead[9].from + offset, parsedhead[9].to + offset2).trim();
547
+ state = (state[0] === 'R' ? 'running' : (state[0] === 'S' ? 'sleeping' : (state[0] === 'T' ? 'stopped' : (state[0] === 'W' ? 'paging' : (state[0] === 'X' ? 'dead' : (state[0] === 'Z' ? 'zombie' : ((state[0] === 'D' || state[0] === 'U') ? 'blocked' : 'unknown')))))));
548
+ checkColumn(10);
549
+ let tty = line.substring(parsedhead[10].from + offset, parsedhead[10].to + offset2).trim();
550
+ if (tty === '?' || tty === '??') { tty = ''; }
551
+ checkColumn(11);
552
+ const user = line.substring(parsedhead[11].from + offset, parsedhead[11].to + offset2).trim();
553
+ checkColumn(12);
554
+ let cmdPath = '';
555
+ let command = '';
556
+ let params = '';
557
+ let fullcommand = line.substring(parsedhead[12].from + offset, parsedhead[12].to + offset2).trim();
558
+ if (fullcommand.substr(fullcommand.length - 1) === ']') { fullcommand = fullcommand.slice(0, -1); }
559
+ if (fullcommand.substr(0, 1) === '[') { command = fullcommand.substring(1); }
560
+ else {
561
+ // try to figure out where parameter starts
562
+ let firstParamPos = fullcommand.indexOf(' -');
563
+ let firstParamPathPos = fullcommand.indexOf(' /');
564
+ firstParamPos = (firstParamPos >= 0 ? firstParamPos : 10000);
565
+ firstParamPathPos = (firstParamPathPos >= 0 ? firstParamPathPos : 10000);
566
+ const firstPos = Math.min(firstParamPos, firstParamPathPos);
567
+ let tmpCommand = fullcommand.substr(0, firstPos);
568
+ const tmpParams = fullcommand.substr(firstPos);
569
+ const lastSlashPos = tmpCommand.lastIndexOf('/');
570
+ if (lastSlashPos >= 0) {
571
+ cmdPath = tmpCommand.substr(0, lastSlashPos);
572
+ tmpCommand = tmpCommand.substr(lastSlashPos + 1);
573
+ }
574
+
575
+ if (firstPos === 10000 && tmpCommand.indexOf(' ') > -1) {
576
+ const parts = tmpCommand.split(' ');
577
+ if (fs.existsSync(path.join(cmdPath, parts[0]))) {
578
+ command = parts.shift();
579
+ params = (parts.join(' ') + ' ' + tmpParams).trim();
580
+ } else {
581
+ command = tmpCommand.trim();
582
+ params = tmpParams.trim();
583
+ }
584
+ } else {
585
+ command = tmpCommand.trim();
586
+ params = tmpParams.trim();
587
+ }
588
+ }
589
+
590
+ return ({
591
+ pid: pid,
592
+ parentPid: ppid,
593
+ name: _linux ? getName(command) : command,
594
+ cpu: cpu,
595
+ cpuu: 0,
596
+ cpus: 0,
597
+ mem: mem,
598
+ priority: priority,
599
+ memVsz: vsz,
600
+ memRss: rss,
601
+ nice: nice,
602
+ started: started,
603
+ state: state,
604
+ tty: tty,
605
+ user: user,
606
+ command: command,
607
+ params: params,
608
+ path: cmdPath
609
+ });
610
+ }
611
+
612
+ function parseProcesses(lines) {
613
+ let result = [];
614
+ if (lines.length > 1) {
615
+ let head = lines[0];
616
+ parsedhead = util.parseHead(head, 8);
617
+ lines.shift();
618
+ lines.forEach(function (line) {
619
+ if (line.trim() !== '') {
620
+ result.push(parseLine(line));
621
+ }
622
+ });
623
+ }
624
+ return result;
625
+ }
626
+ function parseProcesses2(lines) {
627
+
628
+ function formatDateTime(time) {
629
+ const month = ('0' + (time.getMonth() + 1).toString()).substr(-2);
630
+ const year = time.getFullYear().toString();
631
+ const day = ('0' + time.getDay().toString()).substr(-2);
632
+ const hours = time.getHours().toString();
633
+ const mins = time.getMinutes().toString();
634
+ const secs = ('0' + time.getSeconds().toString()).substr(-2);
635
+
636
+ return (year + '-' + month + '-' + day + ' ' + hours + ':' + mins + ':' + secs);
637
+ }
638
+
639
+ let result = [];
640
+ lines.forEach(function (line) {
641
+ if (line.trim() !== '') {
642
+ line = line.trim().replace(/ +/g, ' ').replace(/,+/g, '.');
643
+ const parts = line.split(' ');
644
+ const command = parts.slice(9).join(' ');
645
+ const pmem = parseFloat((1.0 * parseInt(parts[3]) * 1024 / os.totalmem()).toFixed(1));
646
+ const elapsed_parts = parts[5].split(':');
647
+ const started = formatDateTime(new Date(Date.now() - (elapsed_parts.length > 1 ? (elapsed_parts[0] * 60 + elapsed_parts[1]) * 1000 : elapsed_parts[0] * 1000)));
648
+
649
+ result.push({
650
+ pid: parseInt(parts[0]),
651
+ parentPid: parseInt(parts[1]),
652
+ name: getName(command),
653
+ cpu: 0,
654
+ cpuu: 0,
655
+ cpus: 0,
656
+ mem: pmem,
657
+ priority: 0,
658
+ memVsz: parseInt(parts[2]),
659
+ memRss: parseInt(parts[3]),
660
+ nice: parseInt(parts[4]),
661
+ started: started,
662
+ state: (parts[6] === 'R' ? 'running' : (parts[6] === 'S' ? 'sleeping' : (parts[6] === 'T' ? 'stopped' : (parts[6] === 'W' ? 'paging' : (parts[6] === 'X' ? 'dead' : (parts[6] === 'Z' ? 'zombie' : ((parts[6] === 'D' || parts[6] === 'U') ? 'blocked' : 'unknown'))))))),
663
+ tty: parts[7],
664
+ user: parts[8],
665
+ command: command
666
+ });
667
+ }
668
+ });
669
+ return result;
670
+ }
671
+
672
+ return new Promise((resolve) => {
673
+ process.nextTick(() => {
674
+ let result = {
675
+ all: 0,
676
+ running: 0,
677
+ blocked: 0,
678
+ sleeping: 0,
679
+ unknown: 0,
680
+ list: []
681
+ };
682
+
683
+ let cmd = '';
684
+
685
+ if ((_processes_cpu.ms && Date.now() - _processes_cpu.ms >= 500) || _processes_cpu.ms === 0) {
686
+ if (_linux || _freebsd || _openbsd || _netbsd || _darwin || _sunos) {
687
+ if (_linux) { cmd = 'export LC_ALL=C; ps -axo pid:11,ppid:11,pcpu:6,pmem:6,pri:5,vsz:11,rss:11,ni:5,lstart:30,state:5,tty:15,user:20,command; unset LC_ALL'; }
688
+ if (_freebsd || _openbsd || _netbsd) { cmd = 'export LC_ALL=C; ps -axo pid,ppid,pcpu,pmem,pri,vsz,rss,ni,lstart,state,tty,user,command; unset LC_ALL'; }
689
+ if (_darwin) { cmd = 'ps -axo pid,ppid,pcpu,pmem,pri,vsz=xxx_fake_title,rss=fake_title2,nice,lstart,state,tty,user,command -r'; }
690
+ if (_sunos) { cmd = 'ps -Ao pid,ppid,pcpu,pmem,pri,vsz,rss,nice,stime,s,tty,user,comm'; }
691
+ exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
692
+ if (!error && stdout.toString().trim()) {
693
+ result.list = (parseProcesses(stdout.toString().split('\n'))).slice();
694
+ result.all = result.list.length;
695
+ result.running = result.list.filter(function (e) {
696
+ return e.state === 'running';
697
+ }).length;
698
+ result.blocked = result.list.filter(function (e) {
699
+ return e.state === 'blocked';
700
+ }).length;
701
+ result.sleeping = result.list.filter(function (e) {
702
+ return e.state === 'sleeping';
703
+ }).length;
704
+
705
+ if (_linux) {
706
+ // calc process_cpu - ps is not accurate in linux!
707
+ cmd = 'cat /proc/stat | grep "cpu "';
708
+ for (let i = 0; i < result.list.length; i++) {
709
+ cmd += (';cat /proc/' + result.list[i].pid + '/stat');
710
+ }
711
+ exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
712
+ let curr_processes = stdout.toString().split('\n');
713
+
714
+ // first line (all - /proc/stat)
715
+ let all = parseProcStat(curr_processes.shift());
716
+
717
+ // process
718
+ let list_new = {};
719
+ let resultProcess = {};
720
+ for (let i = 0; i < curr_processes.length; i++) {
721
+ resultProcess = calcProcStatLinux(curr_processes[i], all, _processes_cpu);
722
+
723
+ if (resultProcess.pid) {
724
+
725
+ // store pcpu in outer array
726
+ let listPos = result.list.map(function (e) { return e.pid; }).indexOf(resultProcess.pid);
727
+ if (listPos >= 0) {
728
+ result.list[listPos].cpu = resultProcess.cpuu + resultProcess.cpus;
729
+ result.list[listPos].cpuu = resultProcess.cpuu;
730
+ result.list[listPos].cpus = resultProcess.cpus;
731
+ }
732
+
733
+ // save new values
734
+ list_new[resultProcess.pid] = {
735
+ cpuu: resultProcess.cpuu,
736
+ cpus: resultProcess.cpus,
737
+ utime: resultProcess.utime,
738
+ stime: resultProcess.stime,
739
+ cutime: resultProcess.cutime,
740
+ cstime: resultProcess.cstime
741
+ };
742
+ }
743
+ }
744
+
745
+ // store old values
746
+ _processes_cpu.all = all;
747
+ // _processes_cpu.list = list_new;
748
+ _processes_cpu.list = Object.assign({}, list_new);
749
+ _processes_cpu.ms = Date.now() - _processes_cpu.ms;
750
+ // _processes_cpu.result = result;
751
+ _processes_cpu.result = Object.assign({}, result);
752
+ if (callback) { callback(result); }
753
+ resolve(result);
754
+ });
755
+ } else {
756
+ if (callback) { callback(result); }
757
+ resolve(result);
758
+ }
759
+ } else {
760
+ cmd = 'ps -o pid,ppid,vsz,rss,nice,etime,stat,tty,user,comm';
761
+ if (_sunos) {
762
+ cmd = 'ps -o pid,ppid,vsz,rss,nice,etime,s,tty,user,comm';
763
+ }
764
+ exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
765
+ if (!error) {
766
+ let lines = stdout.toString().split('\n');
767
+ lines.shift();
768
+
769
+ result.list = parseProcesses2(lines).slice();
770
+ result.all = result.list.length;
771
+ result.running = result.list.filter(function (e) {
772
+ return e.state === 'running';
773
+ }).length;
774
+ result.blocked = result.list.filter(function (e) {
775
+ return e.state === 'blocked';
776
+ }).length;
777
+ result.sleeping = result.list.filter(function (e) {
778
+ return e.state === 'sleeping';
779
+ }).length;
780
+ if (callback) { callback(result); }
781
+ resolve(result);
782
+ } else {
783
+ if (callback) { callback(result); }
784
+ resolve(result);
785
+ }
786
+ });
787
+ }
788
+ });
789
+ } else if (_windows) {
790
+ try {
791
+ util.powerShell('Get-WmiObject Win32_Process | fl *').then((stdout, error) => {
792
+ if (!error) {
793
+ let processSections = stdout.split(/\n\s*\n/);
794
+ let procs = [];
795
+ let procStats = [];
796
+ let list_new = {};
797
+ let allcpuu = _processes_cpu.all_utime;
798
+ let allcpus = _processes_cpu.all_stime;
799
+ for (let i = 0; i < processSections.length; i++) {
800
+ if (processSections[i].trim() !== '') {
801
+ let lines = processSections[i].trim().split('\r\n');
802
+ let pid = parseInt(util.getValue(lines, 'ProcessId', ':', true), 10);
803
+ let parentPid = parseInt(util.getValue(lines, 'ParentProcessId', ':', true), 10);
804
+ let statusValue = util.getValue(lines, 'ExecutionState', ':');
805
+ let name = util.getValue(lines, 'Caption', ':', true);
806
+ let commandLine = util.getValue(lines, 'CommandLine', ':', true);
807
+ let commandPath = util.getValue(lines, 'ExecutablePath', ':', true);
808
+ let utime = parseInt(util.getValue(lines, 'UserModeTime', ':', true), 10);
809
+ let stime = parseInt(util.getValue(lines, 'KernelModeTime', ':', true), 10);
810
+ let memw = parseInt(util.getValue(lines, 'WorkingSetSize', ':', true), 10);
811
+ allcpuu = allcpuu + utime;
812
+ allcpus = allcpus + stime;
813
+ result.all++;
814
+ if (!statusValue) { result.unknown++; }
815
+ if (statusValue === '3') { result.running++; }
816
+ if (statusValue === '4' || statusValue === '5') { result.blocked++; }
817
+
818
+ procStats.push({
819
+ pid: pid,
820
+ utime: utime,
821
+ stime: stime,
822
+ cpu: 0,
823
+ cpuu: 0,
824
+ cpus: 0,
825
+ });
826
+ procs.push({
827
+ pid: pid,
828
+ parentPid: parentPid,
829
+ name: name,
830
+ cpu: 0,
831
+ cpuu: 0,
832
+ cpus: 0,
833
+ mem: memw / os.totalmem() * 100,
834
+ priority: parseInt(util.getValue(lines, 'Priority', ':', true), 10),
835
+ memVsz: parseInt(util.getValue(lines, 'PageFileUsage', ':', true), 10),
836
+ memRss: Math.floor(parseInt(util.getValue(lines, 'WorkingSetSize', ':', true), 10) / 1024),
837
+ nice: 0,
838
+ started: parseTimeWin(util.getValue(lines, 'CreationDate', ':', true)),
839
+ state: (!statusValue ? _winStatusValues[0] : _winStatusValues[statusValue]),
840
+ tty: '',
841
+ user: '',
842
+ command: commandLine || name,
843
+ path: commandPath,
844
+ params: ''
845
+ });
846
+ }
847
+ }
848
+ result.sleeping = result.all - result.running - result.blocked - result.unknown;
849
+ result.list = procs;
850
+ for (let i = 0; i < procStats.length; i++) {
851
+ let resultProcess = calcProcStatWin(procStats[i], allcpuu + allcpus, _processes_cpu);
852
+
853
+ // store pcpu in outer array
854
+ let listPos = result.list.map(function (e) { return e.pid; }).indexOf(resultProcess.pid);
855
+ if (listPos >= 0) {
856
+ result.list[listPos].cpu = resultProcess.cpuu + resultProcess.cpus;
857
+ result.list[listPos].cpuu = resultProcess.cpuu;
858
+ result.list[listPos].cpus = resultProcess.cpus;
859
+ }
860
+
861
+ // save new values
862
+ list_new[resultProcess.pid] = {
863
+ cpuu: resultProcess.cpuu,
864
+ cpus: resultProcess.cpus,
865
+ utime: resultProcess.utime,
866
+ stime: resultProcess.stime
867
+ };
868
+ }
869
+ // store old values
870
+ _processes_cpu.all = allcpuu + allcpus;
871
+ _processes_cpu.all_utime = allcpuu;
872
+ _processes_cpu.all_stime = allcpus;
873
+ // _processes_cpu.list = list_new;
874
+ _processes_cpu.list = Object.assign({}, list_new);
875
+ _processes_cpu.ms = Date.now() - _processes_cpu.ms;
876
+ // _processes_cpu.result = result;
877
+ _processes_cpu.result = Object.assign({}, result);
878
+ }
879
+ if (callback) {
880
+ callback(result);
881
+ }
882
+ resolve(result);
883
+ });
884
+ } catch (e) {
885
+ if (callback) { callback(result); }
886
+ resolve(result);
887
+ }
888
+ } else {
889
+ if (callback) { callback(result); }
890
+ resolve(result);
891
+ }
892
+ } else {
893
+ if (callback) { callback(_processes_cpu.result); }
894
+ resolve(_processes_cpu.result);
895
+ }
896
+ });
897
+ });
898
+ }
899
+
900
+ exports.processes = processes;
901
+
902
+ // --------------------------
903
+ // PS - process load
904
+ // get detailed information about a certain process
905
+ // (PID, CPU-Usage %, Mem-Usage %)
906
+
907
+ function processLoad(proc, callback) {
908
+
909
+ // fallback - if only callback is given
910
+ if (util.isFunction(proc) && !callback) {
911
+ callback = proc;
912
+ proc = '';
913
+ }
914
+
915
+ return new Promise((resolve) => {
916
+ process.nextTick(() => {
917
+
918
+ proc = proc || '';
919
+
920
+ if (typeof proc !== 'string') {
921
+ if (callback) { callback([]); }
922
+ return resolve([]);
923
+ }
924
+
925
+ let processesString = '';
926
+ processesString.__proto__.toLowerCase = util.stringToLower;
927
+ processesString.__proto__.replace = util.stringReplace;
928
+ processesString.__proto__.trim = util.stringTrim;
929
+
930
+ const s = util.sanitizeShellString(proc);
931
+ for (let i = 0; i <= util.mathMin(s.length, 2000); i++) {
932
+ if (!(s[i] === undefined)) {
933
+ processesString = processesString + s[i];
934
+ }
935
+ }
936
+
937
+ processesString = processesString.trim().toLowerCase().replace(/, /g, '|').replace(/,+/g, '|');
938
+ if (processesString === '') {
939
+ processesString = '*';
940
+ }
941
+ if (util.isPrototypePolluted() && processesString !== '*') {
942
+ processesString = '------';
943
+ }
944
+ let processes = processesString.split('|');
945
+ let result = [];
946
+
947
+ const procSanitized = util.isPrototypePolluted() ? '' : util.sanitizeShellString(proc);
948
+
949
+ // from here new
950
+ // let result = {
951
+ // 'proc': procSanitized,
952
+ // 'pid': null,
953
+ // 'cpu': 0,
954
+ // 'mem': 0
955
+ // };
956
+ if (procSanitized && processes.length && processes[0] !== '------') {
957
+ if (_windows) {
958
+ try {
959
+ util.powerShell('Get-WmiObject Win32_Process | fl *').then((stdout, error) => {
960
+ if (!error) {
961
+ let processSections = stdout.split(/\n\s*\n/);
962
+ let procStats = [];
963
+ let list_new = {};
964
+ let allcpuu = _process_cpu.all_utime;
965
+ let allcpus = _process_cpu.all_stime;
966
+
967
+ // go through all processes
968
+ for (let i = 0; i < processSections.length; i++) {
969
+ if (processSections[i].trim() !== '') {
970
+ let lines = processSections[i].trim().split('\r\n');
971
+ let pid = parseInt(util.getValue(lines, 'ProcessId', ':', true), 10);
972
+ let name = util.getValue(lines, 'Caption', ':', true);
973
+ let utime = parseInt(util.getValue(lines, 'UserModeTime', ':', true), 10);
974
+ let stime = parseInt(util.getValue(lines, 'KernelModeTime', ':', true), 10);
975
+ let mem = parseInt(util.getValue(lines, 'WorkingSetSize', ':', true), 10);
976
+ allcpuu = allcpuu + utime;
977
+ allcpus = allcpus + stime;
978
+
979
+ procStats.push({
980
+ pid: pid,
981
+ name,
982
+ utime: utime,
983
+ stime: stime,
984
+ cpu: 0,
985
+ cpuu: 0,
986
+ cpus: 0,
987
+ mem
988
+ });
989
+ let pname = '';
990
+ let inList = false;
991
+ processes.forEach(function (proc) {
992
+ // console.log(proc)
993
+ // console.log(item)
994
+ // inList = inList || item.name.toLowerCase() === proc.toLowerCase();
995
+ if (name.toLowerCase().indexOf(proc.toLowerCase()) >= 0 && !inList) {
996
+ inList = true;
997
+ pname = proc;
998
+ }
999
+ });
1000
+
1001
+ if (processesString === '*' || inList) {
1002
+ let processFound = false;
1003
+ result.forEach(function (item) {
1004
+ if (item.proc.toLowerCase() === pname.toLowerCase()) {
1005
+ item.pids.push(pid);
1006
+ item.mem += mem / os.totalmem() * 100;
1007
+ processFound = true;
1008
+ }
1009
+ });
1010
+ if (!processFound) {
1011
+ result.push({
1012
+ proc: pname,
1013
+ pid: pid,
1014
+ pids: [pid],
1015
+ cpu: 0,
1016
+ mem: mem / os.totalmem() * 100
1017
+ });
1018
+ }
1019
+ }
1020
+ }
1021
+ }
1022
+ // add missing processes
1023
+ if (processesString !== '*') {
1024
+ let processesMissing = processes.filter(function (name) {
1025
+ // return procStats.filter(function(item) { return item.name.toLowerCase() === name }).length === 0;
1026
+ return procStats.filter(function (item) { return item.name.toLowerCase().indexOf(name) >= 0; }).length === 0;
1027
+
1028
+ });
1029
+ processesMissing.forEach(function (procName) {
1030
+ result.push({
1031
+ proc: procName,
1032
+ pid: null,
1033
+ pids: [],
1034
+ cpu: 0,
1035
+ mem: 0
1036
+ });
1037
+ });
1038
+ }
1039
+
1040
+ // calculate proc stats for each proc
1041
+ for (let i = 0; i < procStats.length; i++) {
1042
+ let resultProcess = calcProcStatWin(procStats[i], allcpuu + allcpus, _process_cpu);
1043
+
1044
+ let listPos = -1;
1045
+ for (let j = 0; j < result.length; j++) {
1046
+ if (result[j].pid === resultProcess.pid || result[j].pids.indexOf(resultProcess.pid) >= 0) { listPos = j; }
1047
+ }
1048
+ if (listPos >= 0) {
1049
+ result[listPos].cpu += resultProcess.cpuu + resultProcess.cpus;
1050
+ }
1051
+
1052
+ // save new values
1053
+ list_new[resultProcess.pid] = {
1054
+ cpuu: resultProcess.cpuu,
1055
+ cpus: resultProcess.cpus,
1056
+ utime: resultProcess.utime,
1057
+ stime: resultProcess.stime
1058
+ };
1059
+ }
1060
+ // store old values
1061
+ _process_cpu.all = allcpuu + allcpus;
1062
+ _process_cpu.all_utime = allcpuu;
1063
+ _process_cpu.all_stime = allcpus;
1064
+ // _process_cpu.list = list_new;
1065
+ _process_cpu.list = Object.assign({}, list_new);
1066
+ _process_cpu.ms = Date.now() - _process_cpu.ms;
1067
+ _process_cpu.result = JSON.parse(JSON.stringify(result));
1068
+ if (callback) {
1069
+ callback(result);
1070
+ }
1071
+ resolve(result);
1072
+ }
1073
+ });
1074
+ } catch (e) {
1075
+ if (callback) { callback(result); }
1076
+ resolve(result);
1077
+ }
1078
+ }
1079
+
1080
+ if (_darwin || _linux || _freebsd || _openbsd || _netbsd) {
1081
+ const params = ['-axo', 'pid,pcpu,pmem,comm'];
1082
+ util.execSafe('ps', params).then((stdout) => {
1083
+ if (stdout) {
1084
+ let procStats = [];
1085
+ let lines = stdout.toString().split('\n').filter(function (line) {
1086
+ if (processesString === '*') { return true; }
1087
+ if (line.toLowerCase().indexOf('grep') !== -1) { return false; } // remove this??
1088
+ let found = false;
1089
+ processes.forEach(function (item) {
1090
+ found = found || (line.toLowerCase().indexOf(item.toLowerCase()) >= 0);
1091
+ });
1092
+ return found;
1093
+ });
1094
+
1095
+ lines.forEach(function (line) {
1096
+ let data = line.trim().replace(/ +/g, ' ').split(' ');
1097
+ if (data.length > 3) {
1098
+ procStats.push({
1099
+ name: data[3].substring(data[3].lastIndexOf('/') + 1),
1100
+ pid: parseInt(data[0]) || 0,
1101
+ cpu: parseFloat(data[1].replace(',', '.')),
1102
+ mem: parseFloat(data[2].replace(',', '.'))
1103
+ });
1104
+ }
1105
+ });
1106
+
1107
+ procStats.forEach(function (item) {
1108
+ let listPos = -1;
1109
+ let inList = false;
1110
+ let name = '';
1111
+ for (let j = 0; j < result.length; j++) {
1112
+ // if (result[j].proc.toLowerCase() === item.name.toLowerCase()) {
1113
+ // if (result[j].proc.toLowerCase().indexOf(item.name.toLowerCase()) >= 0) {
1114
+ if (item.name.toLowerCase().indexOf(result[j].proc.toLowerCase()) >= 0) {
1115
+ listPos = j;
1116
+ }
1117
+ }
1118
+ // console.log(listPos);
1119
+ processes.forEach(function (proc) {
1120
+ // console.log(proc)
1121
+ // console.log(item)
1122
+ // inList = inList || item.name.toLowerCase() === proc.toLowerCase();
1123
+ if (item.name.toLowerCase().indexOf(proc.toLowerCase()) >= 0 && !inList) {
1124
+ inList = true;
1125
+ name = proc;
1126
+ }
1127
+ });
1128
+ // console.log(item);
1129
+ // console.log(listPos);
1130
+ if ((processesString === '*') || inList) {
1131
+ if (listPos < 0) {
1132
+ result.push({
1133
+ proc: name,
1134
+ pid: item.pid,
1135
+ pids: [item.pid],
1136
+ cpu: item.cpu,
1137
+ mem: item.mem
1138
+ });
1139
+ } else {
1140
+ result[listPos].pids.push(item.pid);
1141
+ result[listPos].cpu += item.cpu;
1142
+ result[listPos].mem += item.mem;
1143
+ }
1144
+ }
1145
+ });
1146
+
1147
+ if (processesString !== '*') {
1148
+ // add missing processes
1149
+ let processesMissing = processes.filter(function (name) {
1150
+ return procStats.filter(function (item) { return item.name.toLowerCase().indexOf(name) >= 0; }).length === 0;
1151
+ });
1152
+ processesMissing.forEach(function (procName) {
1153
+ result.push({
1154
+ proc: procName,
1155
+ pid: null,
1156
+ pids: [],
1157
+ cpu: 0,
1158
+ mem: 0
1159
+ });
1160
+ });
1161
+ }
1162
+ if (_linux) {
1163
+ // calc process_cpu - ps is not accurate in linux!
1164
+ result.forEach(function (item) {
1165
+ item.cpu = 0;
1166
+ });
1167
+ let cmd = 'cat /proc/stat | grep "cpu "';
1168
+ for (let i in result) {
1169
+ for (let j in result[i].pids) {
1170
+ cmd += (';cat /proc/' + result[i].pids[j] + '/stat');
1171
+ }
1172
+ }
1173
+ exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
1174
+ let curr_processes = stdout.toString().split('\n');
1175
+
1176
+ // first line (all - /proc/stat)
1177
+ let all = parseProcStat(curr_processes.shift());
1178
+
1179
+ // process
1180
+ let list_new = {};
1181
+ let resultProcess = {};
1182
+
1183
+ for (let i = 0; i < curr_processes.length; i++) {
1184
+ resultProcess = calcProcStatLinux(curr_processes[i], all, _process_cpu);
1185
+
1186
+ if (resultProcess.pid) {
1187
+
1188
+ // find result item
1189
+ let resultItemId = -1;
1190
+ for (let i in result) {
1191
+ if (result[i].pids.indexOf(resultProcess.pid) >= 0) {
1192
+ resultItemId = i;
1193
+ }
1194
+ }
1195
+ // store pcpu in outer result
1196
+ if (resultItemId >= 0) {
1197
+ result[resultItemId].cpu += resultProcess.cpuu + resultProcess.cpus;
1198
+ }
1199
+
1200
+ // save new values
1201
+ list_new[resultProcess.pid] = {
1202
+ cpuu: resultProcess.cpuu,
1203
+ cpus: resultProcess.cpus,
1204
+ utime: resultProcess.utime,
1205
+ stime: resultProcess.stime,
1206
+ cutime: resultProcess.cutime,
1207
+ cstime: resultProcess.cstime
1208
+ };
1209
+ }
1210
+ }
1211
+
1212
+ result.forEach(function (item) {
1213
+ item.cpu = Math.round(item.cpu * 100) / 100;
1214
+ });
1215
+
1216
+ _process_cpu.all = all;
1217
+ // _process_cpu.list = list_new;
1218
+ _process_cpu.list = Object.assign({}, list_new);
1219
+ _process_cpu.ms = Date.now() - _process_cpu.ms;
1220
+ // _process_cpu.result = result;
1221
+ _process_cpu.result = Object.assign({}, result);
1222
+ if (callback) { callback(result); }
1223
+ resolve(result);
1224
+ });
1225
+ } else {
1226
+ if (callback) { callback(result); }
1227
+ resolve(result);
1228
+ }
1229
+ } else {
1230
+ if (callback) { callback(result); }
1231
+ resolve(result);
1232
+ }
1233
+ });
1234
+ }
1235
+ }
1236
+ });
1237
+ });
1238
+ }
1239
+
1240
+ exports.processLoad = processLoad;