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