processes.js 48 KB

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