Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

cpu.js 48KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  1. 'use strict';
  2. // @ts-check
  3. // ==================================================================================
  4. // cpu.js
  5. // ----------------------------------------------------------------------------------
  6. // Description: System Information - library
  7. // for Node.js
  8. // Copyright: (c) 2014 - 2020
  9. // Author: Sebastian Hildebrandt
  10. // ----------------------------------------------------------------------------------
  11. // License: MIT
  12. // ==================================================================================
  13. // 4. CPU
  14. // ----------------------------------------------------------------------------------
  15. const os = require('os');
  16. const exec = require('child_process').exec;
  17. const fs = require('fs');
  18. const util = require('./util');
  19. let _platform = process.platform;
  20. const _linux = (_platform === 'linux');
  21. const _darwin = (_platform === 'darwin');
  22. const _windows = (_platform === 'win32');
  23. const _freebsd = (_platform === 'freebsd');
  24. const _openbsd = (_platform === 'openbsd');
  25. const _netbsd = (_platform === 'netbsd');
  26. const _sunos = (_platform === 'sunos');
  27. let _cpu_speed = '0.00';
  28. let _current_cpu = {
  29. user: 0,
  30. nice: 0,
  31. system: 0,
  32. idle: 0,
  33. irq: 0,
  34. load: 0,
  35. tick: 0,
  36. ms: 0,
  37. currentload: 0,
  38. currentload_user: 0,
  39. currentload_system: 0,
  40. currentload_nice: 0,
  41. currentload_idle: 0,
  42. currentload_irq: 0,
  43. raw_currentload: 0,
  44. raw_currentload_user: 0,
  45. raw_currentload_system: 0,
  46. raw_currentload_nice: 0,
  47. raw_currentload_idle: 0,
  48. raw_currentload_irq: 0
  49. };
  50. let _cpus = [];
  51. let _corecount = 0;
  52. const AMDBaseFrequencies = {
  53. '8346': '1.8',
  54. '8347': '1.9',
  55. '8350': '2.0',
  56. '8354': '2.2',
  57. '8356|SE': '2.4',
  58. '8356': '2.3',
  59. '8360': '2.5',
  60. '2372': '2.1',
  61. '2373': '2.1',
  62. '2374': '2.2',
  63. '2376': '2.3',
  64. '2377': '2.3',
  65. '2378': '2.4',
  66. '2379': '2.4',
  67. '2380': '2.5',
  68. '2381': '2.5',
  69. '2382': '2.6',
  70. '2384': '2.7',
  71. '2386': '2.8',
  72. '2387': '2.8',
  73. '2389': '2.9',
  74. '2393': '3.1',
  75. '8374': '2.2',
  76. '8376': '2.3',
  77. '8378': '2.4',
  78. '8379': '2.4',
  79. '8380': '2.5',
  80. '8381': '2.5',
  81. '8382': '2.6',
  82. '8384': '2.7',
  83. '8386': '2.8',
  84. '8387': '2.8',
  85. '8389': '2.9',
  86. '8393': '3.1',
  87. '2419EE': '1.8',
  88. '2423HE': '2.0',
  89. '2425HE': '2.1',
  90. '2427': '2.2',
  91. '2431': '2.4',
  92. '2435': '2.6',
  93. '2439SE': '2.8',
  94. '8425HE': '2.1',
  95. '8431': '2.4',
  96. '8435': '2.6',
  97. '8439SE': '2.8',
  98. '4122': '2.2',
  99. '4130': '2.6',
  100. '4162EE': '1.7',
  101. '4164EE': '1.8',
  102. '4170HE': '2.1',
  103. '4174HE': '2.3',
  104. '4176HE': '2.4',
  105. '4180': '2.6',
  106. '4184': '2.8',
  107. '6124HE': '1.8',
  108. '6128HE': '2.0',
  109. '6132HE': '2.2',
  110. '6128': '2.0',
  111. '6134': '2.3',
  112. '6136': '2.4',
  113. '6140': '2.6',
  114. '6164HE': '1.7',
  115. '6166HE': '1.8',
  116. '6168': '1.9',
  117. '6172': '2.1',
  118. '6174': '2.2',
  119. '6176': '2.3',
  120. '6176SE': '2.3',
  121. '6180SE': '2.5',
  122. '3250': '2.5',
  123. '3260': '2.7',
  124. '3280': '2.4',
  125. '4226': '2.7',
  126. '4228': '2.8',
  127. '4230': '2.9',
  128. '4234': '3.1',
  129. '4238': '3.3',
  130. '4240': '3.4',
  131. '4256': '1.6',
  132. '4274': '2.5',
  133. '4276': '2.6',
  134. '4280': '2.8',
  135. '4284': '3.0',
  136. '6204': '3.3',
  137. '6212': '2.6',
  138. '6220': '3.0',
  139. '6234': '2.4',
  140. '6238': '2.6',
  141. '6262HE': '1.6',
  142. '6272': '2.1',
  143. '6274': '2.2',
  144. '6276': '2.3',
  145. '6278': '2.4',
  146. '6282SE': '2.6',
  147. '6284SE': '2.7',
  148. '6308': '3.5',
  149. '6320': '2.8',
  150. '6328': '3.2',
  151. '6338P': '2.3',
  152. '6344': '2.6',
  153. '6348': '2.8',
  154. '6366': '1.8',
  155. '6370P': '2.0',
  156. '6376': '2.3',
  157. '6378': '2.4',
  158. '6380': '2.5',
  159. '6386': '2.8',
  160. 'FX|4100': '3.6',
  161. 'FX|4120': '3.9',
  162. 'FX|4130': '3.8',
  163. 'FX|4150': '3.8',
  164. 'FX|4170': '4.2',
  165. 'FX|6100': '3.3',
  166. 'FX|6120': '3.6',
  167. 'FX|6130': '3.6',
  168. 'FX|6200': '3.8',
  169. 'FX|8100': '2.8',
  170. 'FX|8120': '3.1',
  171. 'FX|8140': '3.2',
  172. 'FX|8150': '3.6',
  173. 'FX|8170': '3.9',
  174. 'FX|4300': '3.8',
  175. 'FX|4320': '4.0',
  176. 'FX|4350': '4.2',
  177. 'FX|6300': '3.5',
  178. 'FX|6350': '3.9',
  179. 'FX|8300': '3.3',
  180. 'FX|8310': '3.4',
  181. 'FX|8320': '3.5',
  182. 'FX|8350': '4.0',
  183. 'FX|8370': '4.0',
  184. 'FX|9370': '4.4',
  185. 'FX|9590': '4.7',
  186. 'FX|8320E': '3.2',
  187. 'FX|8370E': '3.3',
  188. '1950X': '3.4',
  189. '1920X': '3.5',
  190. '1920': '3.2',
  191. '1900X': '3.8',
  192. '1800X': '3.6',
  193. '1700X': '3.4',
  194. 'Pro 1700X': '3.5',
  195. '1700': '3.0',
  196. 'Pro 1700': '3.0',
  197. '1600X': '3.6',
  198. '1600': '3.2',
  199. 'Pro 1600': '3.2',
  200. '1500X': '3.5',
  201. 'Pro 1500': '3.5',
  202. '1400': '3.2',
  203. '1300X': '3.5',
  204. 'Pro 1300': '3.5',
  205. '1200': '3.1',
  206. 'Pro 1200': '3.1',
  207. '2200U': '2.5',
  208. '2300U': '2.0',
  209. 'Pro 2300U': '2.0',
  210. '2500U': '2.0',
  211. 'Pro 2500U': '2.2',
  212. '2700U': '2.0',
  213. 'Pro 2700U': '2.2',
  214. '2600H': '3.2',
  215. '2800H': '3.3',
  216. '7601': '2.2',
  217. '7551': '2.0',
  218. '7501': '2.0',
  219. '74501': '2.3',
  220. '7401': '2.0',
  221. '7351': '2.4',
  222. '7301': '2.2',
  223. '7281': '2.1',
  224. '7251': '2.1',
  225. '7551P': '2.0',
  226. '7401P': '2.0',
  227. '7351P': '2.4',
  228. '2300X': '3.5',
  229. '2500X': '3.6',
  230. '2600': '3.4',
  231. '2600E': '3.1',
  232. '2600X': '3.6',
  233. '2700': '3.2',
  234. '2700E': '2.8',
  235. '2700X': '3.7',
  236. 'Pro 2700X': '3.6',
  237. '2920': '3.5',
  238. '2950': '3.5',
  239. '2970WX': '3.0',
  240. '2990WX': '3.0',
  241. '3200U': '2.6',
  242. '3300U': '2.1',
  243. '3500U': '2.1',
  244. '3550H': '2.1',
  245. '3580U': '2.1',
  246. '3700U': '2.3',
  247. '3750H': '2.3',
  248. '3780U': '2.3',
  249. '3500X': '3.6',
  250. '3600': '3.6',
  251. 'Pro 3600': '3.6',
  252. '3600X': '3.8',
  253. 'Pro 3700': '3.6',
  254. '3700X': '3.6',
  255. '3800X': '3.9',
  256. '3900': '3.1',
  257. 'Pro 3900': '3.1',
  258. '3900X': '3.8',
  259. '3950X': '3.5',
  260. '3960X': '3.8',
  261. '3970X': '3.7',
  262. '7232P': '3.1',
  263. '7302P': '3.0',
  264. '7402P': '2.8',
  265. '7502P': '2.5',
  266. '7702P': '2.0',
  267. '7252': '3.1',
  268. '7262': '3.2',
  269. '7272': '2.9',
  270. '7282': '2.8',
  271. '7302': '3.0',
  272. '7352': '2.3',
  273. '7402': '2.8',
  274. '7452': '2.35',
  275. '7502': '2.5',
  276. '7542': '2.9',
  277. '7552': '2.2',
  278. '7642': '2.3',
  279. '7702': '2.0',
  280. '7742': '2.25',
  281. '7H12': '2.6'
  282. };
  283. const socketTypes = {
  284. 1: 'Other',
  285. 2: 'Unknown',
  286. 3: 'Daughter Board',
  287. 4: 'ZIF Socket',
  288. 5: 'Replacement/Piggy Back',
  289. 6: 'None',
  290. 7: 'LIF Socket',
  291. 8: 'Slot 1',
  292. 9: 'Slot 2',
  293. 10: '370 Pin Socket',
  294. 11: 'Slot A',
  295. 12: 'Slot M',
  296. 13: '423',
  297. 14: 'A (Socket 462)',
  298. 15: '478',
  299. 16: '754',
  300. 17: '940',
  301. 18: '939',
  302. 19: 'mPGA604',
  303. 20: 'LGA771',
  304. 21: 'LGA775',
  305. 22: 'S1',
  306. 23: 'AM2',
  307. 24: 'F (1207)',
  308. 25: 'LGA1366',
  309. 26: 'G34',
  310. 27: 'AM3',
  311. 28: 'C32',
  312. 29: 'LGA1156',
  313. 30: 'LGA1567',
  314. 31: 'PGA988A',
  315. 32: 'BGA1288',
  316. 33: 'rPGA988B',
  317. 34: 'BGA1023',
  318. 35: 'BGA1224',
  319. 36: 'LGA1155',
  320. 37: 'LGA1356',
  321. 38: 'LGA2011',
  322. 39: 'FS1',
  323. 40: 'FS2',
  324. 41: 'FM1',
  325. 42: 'FM2',
  326. 43: 'LGA2011-3',
  327. 44: 'LGA1356-3',
  328. 45: 'LGA1150',
  329. 46: 'BGA1168',
  330. 47: 'BGA1234',
  331. 48: 'BGA1364',
  332. 49: 'AM4',
  333. 50: 'LGA1151',
  334. 51: 'BGA1356',
  335. 52: 'BGA1440',
  336. 53: 'BGA1515',
  337. 54: 'LGA3647-1',
  338. 55: 'SP3',
  339. 56: 'SP3r2',
  340. 57: 'LGA2066',
  341. 58: 'BGA1392',
  342. 59: 'BGA1510',
  343. 60: 'BGA1528'
  344. };
  345. function cpuBrandManufacturer(res) {
  346. res.brand = res.brand.replace(/\(R\)+/g, '®').replace(/\s+/g, ' ').trim();
  347. res.brand = res.brand.replace(/\(TM\)+/g, '™').replace(/\s+/g, ' ').trim();
  348. res.brand = res.brand.replace(/\(C\)+/g, '©').replace(/\s+/g, ' ').trim();
  349. res.brand = res.brand.replace(/CPU+/g, '').replace(/\s+/g, ' ').trim();
  350. res.manufacturer = res.brand.split(' ')[0];
  351. let parts = res.brand.split(' ');
  352. parts.shift();
  353. res.brand = parts.join(' ');
  354. return res;
  355. }
  356. function getAMDSpeed(brand) {
  357. let result = '0.00';
  358. for (let key in AMDBaseFrequencies) {
  359. if ({}.hasOwnProperty.call(AMDBaseFrequencies, key)) {
  360. let parts = key.split('|');
  361. let found = 0;
  362. parts.forEach(item => {
  363. if (brand.indexOf(item) > -1) {
  364. found++;
  365. }
  366. });
  367. if (found === parts.length) {
  368. result = AMDBaseFrequencies[key];
  369. }
  370. }
  371. }
  372. return result;
  373. }
  374. // --------------------------
  375. // CPU - brand, speed
  376. function getCpu() {
  377. return new Promise((resolve) => {
  378. process.nextTick(() => {
  379. const UNKNOWN = 'unknown';
  380. let result = {
  381. manufacturer: UNKNOWN,
  382. brand: UNKNOWN,
  383. vendor: '',
  384. family: '',
  385. model: '',
  386. stepping: '',
  387. revision: '',
  388. voltage: '',
  389. speed: '0.00',
  390. speedmin: '',
  391. speedmax: '',
  392. governor: '',
  393. cores: util.cores(),
  394. physicalCores: util.cores(),
  395. processors: 1,
  396. socket: '',
  397. cache: {}
  398. };
  399. if (_darwin) {
  400. exec('sysctl machdep.cpu hw.cpufrequency_max hw.cpufrequency_min hw.packages hw.physicalcpu_max hw.ncpu', function (error, stdout) {
  401. // if (!error) {
  402. let lines = stdout.toString().split('\n');
  403. const modelline = util.getValue(lines, 'machdep.cpu.brand_string');
  404. const modellineParts = modelline.split('@');
  405. result.brand = modellineParts[0].trim();
  406. result.speed = modellineParts[1] ? modellineParts[1].trim() : '0';
  407. result.speed = parseFloat(result.speed.replace(/GHz+/g, '')).toFixed(2);
  408. _cpu_speed = result.speed;
  409. result = cpuBrandManufacturer(result);
  410. result.speedmin = (util.getValue(lines, 'hw.cpufrequency_min') / 1000000000.0).toFixed(2);
  411. result.speedmax = (util.getValue(lines, 'hw.cpufrequency_max') / 1000000000.0).toFixed(2);
  412. result.vendor = util.getValue(lines, 'machdep.cpu.vendor');
  413. result.family = util.getValue(lines, 'machdep.cpu.family');
  414. result.model = util.getValue(lines, 'machdep.cpu.model');
  415. result.stepping = util.getValue(lines, 'machdep.cpu.stepping');
  416. const countProcessors = util.getValue(lines, 'hw.packages');
  417. const countCores = util.getValue(lines, 'hw.physicalcpu_max');
  418. const countThreads = util.getValue(lines, 'hw.ncpu');
  419. if (countProcessors) {
  420. result.processors = parseInt(countProcessors) || 1;
  421. }
  422. if (countCores && countThreads) {
  423. result.cores = parseInt(countThreads) || util.cores();
  424. result.physicalCores = parseInt(countCores) || util.cores();
  425. }
  426. // }
  427. cpuCache().then(res => {
  428. result.cache = res;
  429. resolve(result);
  430. });
  431. });
  432. }
  433. if (_linux) {
  434. let modelline = '';
  435. let lines = [];
  436. if (os.cpus()[0] && os.cpus()[0].model) modelline = os.cpus()[0].model;
  437. exec('export LC_ALL=C; lscpu; echo -n "Governor: "; cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null; echo; unset LC_ALL', function (error, stdout) {
  438. if (!error) {
  439. lines = stdout.toString().split('\n');
  440. }
  441. modelline = util.getValue(lines, 'model name') || modelline;
  442. const modellineParts = modelline.split('@');
  443. result.brand = modellineParts[0].trim();
  444. result.speed = modellineParts[1] ? parseFloat(modellineParts[1].trim()).toFixed(2) : '0.00';
  445. if (result.speed === '0.00' && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) {
  446. result.speed = getAMDSpeed(result.brand);
  447. }
  448. if (result.speed === '0.00') {
  449. let current = getCpuCurrentSpeedSync();
  450. if (current.avg !== 0) result.speed = current.avg.toFixed(2);
  451. }
  452. _cpu_speed = result.speed;
  453. result.speedmin = Math.round(parseFloat(util.getValue(lines, 'cpu min mhz').replace(/,/g, '.')) / 10.0) / 100;
  454. result.speedmin = result.speedmin ? parseFloat(result.speedmin).toFixed(2) : '';
  455. result.speedmax = Math.round(parseFloat(util.getValue(lines, 'cpu max mhz').replace(/,/g, '.')) / 10.0) / 100;
  456. result.speedmax = result.speedmax ? parseFloat(result.speedmax).toFixed(2) : '';
  457. result = cpuBrandManufacturer(result);
  458. result.vendor = util.getValue(lines, 'vendor id');
  459. // if (!result.vendor) { result.vendor = util.getValue(lines, 'anbieterkennung'); }
  460. result.family = util.getValue(lines, 'cpu family');
  461. // if (!result.family) { result.family = util.getValue(lines, 'prozessorfamilie'); }
  462. result.model = util.getValue(lines, 'model:');
  463. // if (!result.model) { result.model = util.getValue(lines, 'modell:'); }
  464. result.stepping = util.getValue(lines, 'stepping');
  465. result.revision = util.getValue(lines, 'cpu revision');
  466. result.cache.l1d = util.getValue(lines, 'l1d cache');
  467. if (result.cache.l1d) { result.cache.l1d = parseInt(result.cache.l1d) * (result.cache.l1d.indexOf('K') !== -1 ? 1024 : 1); }
  468. result.cache.l1i = util.getValue(lines, 'l1i cache');
  469. if (result.cache.l1i) { result.cache.l1i = parseInt(result.cache.l1i) * (result.cache.l1i.indexOf('K') !== -1 ? 1024 : 1); }
  470. result.cache.l2 = util.getValue(lines, 'l2 cache');
  471. if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * (result.cache.l2.indexOf('K') !== -1 ? 1024 : 1); }
  472. result.cache.l3 = util.getValue(lines, 'l3 cache');
  473. if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * (result.cache.l3.indexOf('K') !== -1 ? 1024 : 1); }
  474. const threadsPerCore = util.getValue(lines, 'thread(s) per core') || '1';
  475. // const coresPerSocketInt = parseInt(util.getValue(lines, 'cores(s) per socket') || '1', 10);
  476. const processors = util.getValue(lines, 'socket(s)') || '1';
  477. let threadsPerCoreInt = parseInt(threadsPerCore, 10);
  478. let processorsInt = parseInt(processors, 10);
  479. result.physicalCores = result.cores / threadsPerCoreInt;
  480. result.processors = processorsInt;
  481. result.governor = util.getValue(lines, 'governor') || '';
  482. // Test Raspberry
  483. if (result.vendor === 'ARM') {
  484. const linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
  485. const rPIRevision = util.decodePiCpuinfo(linesRpi);
  486. if (rPIRevision.model.toLowerCase().indexOf('raspberry') >= 0) {
  487. result.family = result.manufacturer;
  488. result.manufacturer = rPIRevision.manufacturer;
  489. result.brand = rPIRevision.processor;
  490. result.revision = rPIRevision.revisionCode;
  491. result.socket = 'SOC';
  492. }
  493. }
  494. // socket type
  495. let lines2 = [];
  496. exec('export LC_ALL=C; dmidecode –t 4 2>/dev/null | grep "Upgrade: Socket"; unset LC_ALL', function (error2, stdout2) {
  497. lines2 = stdout2.toString().split('\n');
  498. if (lines2 && lines2.length) {
  499. result.socket = util.getValue(lines2, 'Upgrade').replace('Socket', '').trim() || result.socket;
  500. }
  501. resolve(result);
  502. });
  503. });
  504. }
  505. if (_freebsd || _openbsd || _netbsd) {
  506. let modelline = '';
  507. let lines = [];
  508. if (os.cpus()[0] && os.cpus()[0].model) modelline = os.cpus()[0].model;
  509. exec('export LC_ALL=C; dmidecode -t 4; dmidecode -t 7 unset LC_ALL', function (error, stdout) {
  510. let cache = [];
  511. if (!error) {
  512. const data = stdout.toString().split('# dmidecode');
  513. const processor = data.length > 1 ? data[1] : '';
  514. cache = data.length > 2 ? data[2].split('Cache Information') : [];
  515. lines = processor.split('\n');
  516. }
  517. result.brand = modelline.split('@')[0].trim();
  518. result.speed = modelline.split('@')[1] ? parseFloat(modelline.split('@')[1].trim()).toFixed(2) : '0.00';
  519. if (result.speed === '0.00' && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) {
  520. result.speed = getAMDSpeed(result.brand);
  521. }
  522. if (result.speed === '0.00') {
  523. let current = getCpuCurrentSpeedSync();
  524. if (current.avg !== 0) result.speed = current.avg.toFixed(2);
  525. }
  526. _cpu_speed = result.speed;
  527. result.speedmin = '';
  528. result.speedmax = Math.round(parseFloat(util.getValue(lines, 'max speed').replace(/Mhz/g, '')) / 10.0) / 100;
  529. result.speedmax = result.speedmax ? parseFloat(result.speedmax).toFixed(2) : '';
  530. result = cpuBrandManufacturer(result);
  531. result.vendor = util.getValue(lines, 'manufacturer');
  532. let sig = util.getValue(lines, 'signature');
  533. sig = sig.split(',');
  534. for (var i = 0; i < sig.length; i++) {
  535. sig[i] = sig[i].trim();
  536. }
  537. result.family = util.getValue(sig, 'Family', ' ', true);
  538. result.model = util.getValue(sig, 'Model', ' ', true);
  539. result.stepping = util.getValue(sig, 'Stepping', ' ', true);
  540. result.revision = '';
  541. const voltage = parseFloat(util.getValue(lines, 'voltage'));
  542. result.voltage = isNaN(voltage) ? '' : voltage.toFixed(2);
  543. for (let i = 0; i < cache.length; i++) {
  544. lines = cache[i].split('\n');
  545. let cacheType = util.getValue(lines, 'Socket Designation').toLowerCase().replace(' ', '-').split('-');
  546. cacheType = cacheType.length ? cacheType[0] : '';
  547. const sizeParts = util.getValue(lines, 'Installed Size').split(' ');
  548. let size = parseInt(sizeParts[0], 10);
  549. const unit = sizeParts.length > 1 ? sizeParts[1] : 'kb';
  550. size = size * (unit === 'kb' ? 1024 : (unit === 'mb' ? 1024 * 1024 : (unit === 'gb' ? 1024 * 1024 * 1024 : 1)));
  551. if (cacheType) {
  552. if (cacheType === 'l1') {
  553. result.cache[cacheType + 'd'] = size / 2;
  554. result.cache[cacheType + 'i'] = size / 2;
  555. } else {
  556. result.cache[cacheType] = size;
  557. }
  558. }
  559. }
  560. // socket type
  561. result.socket = util.getValue(lines, 'Upgrade').replace('Socket', '').trim();
  562. // # threads / # cores
  563. const threadCount = util.getValue(lines, 'thread count').trim();
  564. const coreCount = util.getValue(lines, 'core count').trim();
  565. if (coreCount && threadCount) {
  566. result.cores = threadCount;
  567. result.physicalCores = coreCount;
  568. }
  569. resolve(result);
  570. });
  571. }
  572. if (_sunos) {
  573. resolve(result);
  574. }
  575. if (_windows) {
  576. try {
  577. util.wmic('cpu get /value').then((stdout, error) => {
  578. if (!error) {
  579. let lines = stdout.split('\r\n');
  580. let name = util.getValue(lines, 'name', '=') || '';
  581. if (name.indexOf('@') >= 0) {
  582. result.brand = name.split('@')[0].trim();
  583. result.speed = name.split('@')[1] ? parseFloat(name.split('@')[1].trim()).toFixed(2) : '0.00';
  584. _cpu_speed = result.speed;
  585. } else {
  586. result.brand = name.trim();
  587. result.speed = '0.00';
  588. }
  589. result = cpuBrandManufacturer(result);
  590. result.revision = util.getValue(lines, 'revision', '=');
  591. result.cache.l1d = 0;
  592. result.cache.l1i = 0;
  593. result.cache.l2 = util.getValue(lines, 'l2cachesize', '=');
  594. result.cache.l3 = util.getValue(lines, 'l3cachesize', '=');
  595. if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2, 10) * 1024; }
  596. if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3, 10) * 1024; }
  597. result.vendor = util.getValue(lines, 'manufacturer', '=');
  598. result.speedmax = Math.round(parseFloat(util.getValue(lines, 'maxclockspeed', '=').replace(/,/g, '.')) / 10.0) / 100;
  599. result.speedmax = result.speedmax ? parseFloat(result.speedmax).toFixed(2) : '';
  600. if (result.speed === '0.00' && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) {
  601. result.speed = getAMDSpeed(result.brand);
  602. }
  603. if (result.speed === '0.00') {
  604. result.speed = result.speedmax;
  605. }
  606. let description = util.getValue(lines, 'description', '=').split(' ');
  607. for (let i = 0; i < description.length; i++) {
  608. if (description[i].toLowerCase().startsWith('family') && (i + 1) < description.length && description[i + 1]) {
  609. result.family = description[i + 1];
  610. }
  611. if (description[i].toLowerCase().startsWith('model') && (i + 1) < description.length && description[i + 1]) {
  612. result.model = description[i + 1];
  613. }
  614. if (description[i].toLowerCase().startsWith('stepping') && (i + 1) < description.length && description[i + 1]) {
  615. result.stepping = description[i + 1];
  616. }
  617. }
  618. // socket type
  619. const socketId = util.getValue(lines, 'UpgradeMethod', '=');
  620. if (socketTypes[socketId]) {
  621. result.socket = socketTypes[socketId];
  622. }
  623. // # threads / # cores
  624. const countProcessors = util.countLines(lines, 'Caption');
  625. const countThreads = util.getValue(lines, 'NumberOfLogicalProcessors', '=');
  626. const countCores = util.getValue(lines, 'NumberOfCores', '=');
  627. if (countProcessors) {
  628. result.processors = parseInt(countProcessors) || 1;
  629. }
  630. if (countCores && countThreads) {
  631. result.cores = parseInt(countThreads) || util.cores();
  632. result.physicalCores = parseInt(countCores) || util.cores();
  633. }
  634. if (countProcessors > 1) {
  635. result.cores = result.cores * countProcessors;
  636. result.physicalCores = result.physicalCores * countProcessors;
  637. }
  638. }
  639. util.wmic('path Win32_CacheMemory get CacheType,InstalledSize,Purpose').then((stdout, error) => {
  640. if (!error) {
  641. let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0);
  642. lines.forEach(function (line) {
  643. if (line !== '') {
  644. line = line.trim().split(/\s\s+/);
  645. // L1 Instructions
  646. if (line[2] === 'L1 Cache' && line[0] === '3') {
  647. result.cache.l1i = parseInt(line[1], 10);
  648. }
  649. // L1 Data
  650. if (line[2] === 'L1 Cache' && line[0] === '4') {
  651. result.cache.l1d = parseInt(line[1], 10);
  652. }
  653. }
  654. });
  655. }
  656. resolve(result);
  657. });
  658. });
  659. } catch (e) {
  660. resolve(result);
  661. }
  662. }
  663. });
  664. });
  665. }
  666. // --------------------------
  667. // CPU - Processor Data
  668. function cpu(callback) {
  669. return new Promise((resolve) => {
  670. process.nextTick(() => {
  671. getCpu().then(result => {
  672. if (callback) { callback(result); }
  673. resolve(result);
  674. });
  675. });
  676. });
  677. }
  678. exports.cpu = cpu;
  679. // --------------------------
  680. // CPU - current speed - in GHz
  681. function getCpuCurrentSpeedSync() {
  682. let cpus = os.cpus();
  683. let minFreq = 999999999;
  684. let maxFreq = 0;
  685. let avgFreq = 0;
  686. let cores = [];
  687. if (cpus && cpus.length) {
  688. for (let i in cpus) {
  689. if ({}.hasOwnProperty.call(cpus, i)) {
  690. avgFreq = avgFreq + cpus[i].speed;
  691. if (cpus[i].speed > maxFreq) maxFreq = cpus[i].speed;
  692. if (cpus[i].speed < minFreq) minFreq = cpus[i].speed;
  693. }
  694. cores.push(parseFloat(((cpus[i].speed + 1) / 1000).toFixed(2)));
  695. }
  696. avgFreq = avgFreq / cpus.length;
  697. return {
  698. min: parseFloat(((minFreq + 1) / 1000).toFixed(2)),
  699. max: parseFloat(((maxFreq + 1) / 1000).toFixed(2)),
  700. avg: parseFloat(((avgFreq + 1) / 1000).toFixed(2)),
  701. cores: cores
  702. };
  703. } else {
  704. return {
  705. min: 0,
  706. max: 0,
  707. avg: 0,
  708. cores: cores
  709. };
  710. }
  711. }
  712. function cpuCurrentspeed(callback) {
  713. return new Promise((resolve) => {
  714. process.nextTick(() => {
  715. let result = getCpuCurrentSpeedSync();
  716. if (result.avg === 0 && _cpu_speed !== '0.00') {
  717. const currCpuSpeed = parseFloat(_cpu_speed);
  718. result = {
  719. min: currCpuSpeed,
  720. max: currCpuSpeed,
  721. avg: currCpuSpeed,
  722. cores: []
  723. };
  724. }
  725. if (callback) { callback(result); }
  726. resolve(result);
  727. });
  728. });
  729. }
  730. exports.cpuCurrentspeed = cpuCurrentspeed;
  731. // --------------------------
  732. // CPU - temperature
  733. // if sensors are installed
  734. function cpuTemperature(callback) {
  735. return new Promise((resolve) => {
  736. process.nextTick(() => {
  737. let result = {
  738. main: -1.0,
  739. cores: [],
  740. max: -1.0
  741. };
  742. if (_linux) {
  743. const cmd = 'for mon in /sys/class/hwmon/hwmon*; do for label in "$mon"/temp*_label; do if [ -f $label ]; then value=$(echo $label | rev | cut -c 7- | rev)_input; if [ -f "$value" ]; then echo $(cat "$label")___$(cat "$value"); fi; fi; done; done;';
  744. try {
  745. exec(cmd, function (error, stdout) {
  746. let lines = stdout.toString().split('\n');
  747. lines.forEach(line => {
  748. const parts = line.split('___');
  749. const label = parts[0];
  750. const value = parts.length > 1 && parts[1] ? parts[1] : '0';
  751. if (value && (label === undefined || (label && label.toLowerCase().startsWith('core')))) {
  752. result.cores.push(Math.round(parseInt(value, 10) / 100) / 10);
  753. } else if (value && label && result.main === -1) {
  754. result.main = Math.round(parseInt(value, 10) / 100) / 10;
  755. }
  756. });
  757. if (result.cores.length > 0) {
  758. if (result.main === -1) {
  759. result.main = Math.round(result.cores.reduce((a, b) => a + b, 0) / result.cores.length);
  760. }
  761. let maxtmp = Math.max.apply(Math, result.cores);
  762. result.max = (maxtmp > result.main) ? maxtmp : result.main;
  763. }
  764. if (result.main !== -1) {
  765. if (result.max === -1) {
  766. result.max = result.main;
  767. }
  768. if (callback) { callback(result); }
  769. resolve(result);
  770. return;
  771. }
  772. // }
  773. exec('sensors', function (error, stdout) {
  774. if (!error) {
  775. let lines = stdout.toString().split('\n');
  776. let tdieTemp = -1;
  777. lines.forEach(function (line) {
  778. let regex = /[+-]([^°]*)/g;
  779. let temps = line.match(regex);
  780. let firstPart = line.split(':')[0].toUpperCase();
  781. if (firstPart.indexOf('PHYSICAL') !== -1 || firstPart.indexOf('PACKAGE') !== -1) {
  782. result.main = parseFloat(temps);
  783. }
  784. if (firstPart.indexOf('CORE ') !== -1) {
  785. result.cores.push(parseFloat(temps));
  786. }
  787. if (firstPart.indexOf('TDIE') !== -1 && tdieTemp === -1) {
  788. tdieTemp = parseFloat(temps);
  789. }
  790. });
  791. if (result.cores.length > 0) {
  792. if (result.main === -1) {
  793. result.main = Math.round(result.cores.reduce((a, b) => a + b, 0) / result.cores.length);
  794. }
  795. let maxtmp = Math.max.apply(Math, result.cores);
  796. result.max = (maxtmp > result.main) ? maxtmp : result.main;
  797. } else {
  798. if (result.main === -1 && tdieTemp !== -1) {
  799. result.main = tdieTemp;
  800. result.max = tdieTemp;
  801. }
  802. }
  803. if (result.main !== -1.0 || result.max !== -1.0) {
  804. if (callback) { callback(result); }
  805. resolve(result);
  806. return;
  807. }
  808. }
  809. fs.stat('/sys/class/thermal/thermal_zone0/temp', function (err) {
  810. if (err === null) {
  811. fs.readFile('/sys/class/thermal/thermal_zone0/temp', function (error, stdout) {
  812. if (!error) {
  813. let lines = stdout.toString().split('\n');
  814. if (lines.length > 0) {
  815. result.main = parseFloat(lines[0]) / 1000.0;
  816. result.max = result.main;
  817. }
  818. }
  819. if (callback) { callback(result); }
  820. resolve(result);
  821. });
  822. } else {
  823. exec('/opt/vc/bin/vcgencmd measure_temp', function (error, stdout) {
  824. if (!error) {
  825. let lines = stdout.toString().split('\n');
  826. if (lines.length > 0 && lines[0].indexOf('=')) {
  827. result.main = parseFloat(lines[0].split('=')[1]);
  828. result.max = result.main;
  829. }
  830. }
  831. if (callback) { callback(result); }
  832. resolve(result);
  833. });
  834. }
  835. });
  836. });
  837. });
  838. } catch (er) {
  839. if (callback) { callback(result); }
  840. resolve(result);
  841. }
  842. }
  843. if (_freebsd || _openbsd || _netbsd) {
  844. exec('sysctl dev.cpu | grep temp', function (error, stdout) {
  845. if (!error) {
  846. let lines = stdout.toString().split('\n');
  847. let sum = 0;
  848. lines.forEach(function (line) {
  849. const parts = line.split(':');
  850. if (parts.length > 1) {
  851. const temp = parseFloat(parts[1].replace(',', '.'));
  852. if (temp > result.max) result.max = temp;
  853. sum = sum + temp;
  854. result.cores.push(temp);
  855. }
  856. });
  857. if (result.cores.length) {
  858. result.main = Math.round(sum / result.cores.length * 100) / 100;
  859. }
  860. }
  861. if (callback) { callback(result); }
  862. resolve(result);
  863. });
  864. }
  865. if (_darwin) {
  866. let osxTemp = null;
  867. try {
  868. osxTemp = require('osx-temperature-sensor');
  869. } catch (er) {
  870. osxTemp = null;
  871. }
  872. if (osxTemp) {
  873. result = osxTemp.cpuTemperature();
  874. }
  875. if (callback) { callback(result); }
  876. resolve(result);
  877. }
  878. if (_sunos) {
  879. if (callback) { callback(result); }
  880. resolve(result);
  881. }
  882. if (_windows) {
  883. try {
  884. util.wmic('/namespace:\\\\root\\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature').then((stdout, error) => {
  885. if (!error) {
  886. let sum = 0;
  887. let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0);
  888. lines.forEach(function (line) {
  889. let value = (parseInt(line, 10) - 2732) / 10;
  890. sum = sum + value;
  891. if (value > result.max) result.max = value;
  892. result.cores.push(value);
  893. });
  894. if (result.cores.length) {
  895. result.main = sum / result.cores.length;
  896. }
  897. }
  898. if (callback) { callback(result); }
  899. resolve(result);
  900. });
  901. } catch (e) {
  902. if (callback) { callback(result); }
  903. resolve(result);
  904. }
  905. }
  906. });
  907. });
  908. }
  909. exports.cpuTemperature = cpuTemperature;
  910. // --------------------------
  911. // CPU Flags
  912. function cpuFlags(callback) {
  913. return new Promise((resolve) => {
  914. process.nextTick(() => {
  915. let result = '';
  916. if (_windows) {
  917. try {
  918. exec('reg query "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0" /v FeatureSet', util.execOptsWin, function (error, stdout) {
  919. if (!error) {
  920. let flag_hex = stdout.split('0x').pop().trim();
  921. let flag_bin_unpadded = parseInt(flag_hex, 16).toString(2);
  922. let flag_bin = '0'.repeat(32 - flag_bin_unpadded.length) + flag_bin_unpadded;
  923. // empty flags are the reserved fields in the CPUID feature bit list
  924. // as found on wikipedia:
  925. // https://en.wikipedia.org/wiki/CPUID
  926. let all_flags = [
  927. 'fpu', 'vme', 'de', 'pse', 'tsc', 'msr', 'pae', 'mce', 'cx8', 'apic',
  928. '', 'sep', 'mtrr', 'pge', 'mca', 'cmov', 'pat', 'pse-36', 'psn', 'clfsh',
  929. '', 'ds', 'acpi', 'mmx', 'fxsr', 'sse', 'sse2', 'ss', 'htt', 'tm', 'ia64', 'pbe'
  930. ];
  931. for (let f = 0; f < all_flags.length; f++) {
  932. if (flag_bin[f] === '1' && all_flags[f] !== '') {
  933. result += ' ' + all_flags[f];
  934. }
  935. }
  936. result = result.trim();
  937. }
  938. if (callback) { callback(result); }
  939. resolve(result);
  940. });
  941. } catch (e) {
  942. if (callback) { callback(result); }
  943. resolve(result);
  944. }
  945. }
  946. if (_linux) {
  947. try {
  948. exec('export LC_ALL=C; lscpu; unset LC_ALL', function (error, stdout) {
  949. if (!error) {
  950. let lines = stdout.toString().split('\n');
  951. lines.forEach(function (line) {
  952. if (line.split(':')[0].toUpperCase().indexOf('FLAGS') !== -1) {
  953. result = line.split(':')[1].trim().toLowerCase();
  954. }
  955. });
  956. }
  957. if (!result) {
  958. fs.readFile('/proc/cpuinfo', function (error, stdout) {
  959. if (!error) {
  960. let lines = stdout.toString().split('\n');
  961. result = util.getValue(lines, 'features', ':', true).toLowerCase();
  962. }
  963. if (callback) { callback(result); }
  964. resolve(result);
  965. });
  966. } else {
  967. if (callback) { callback(result); }
  968. resolve(result);
  969. }
  970. });
  971. } catch (e) {
  972. if (callback) { callback(result); }
  973. resolve(result);
  974. }
  975. }
  976. if (_freebsd || _openbsd || _netbsd) {
  977. exec('export LC_ALL=C; dmidecode -t 4 2>/dev/null; unset LC_ALL', function (error, stdout) {
  978. let flags = [];
  979. if (!error) {
  980. let parts = stdout.toString().split('\tFlags:');
  981. const lines = parts.length > 1 ? parts[1].split('\tVersion:')[0].split['\n'] : [];
  982. lines.forEach(function (line) {
  983. let flag = (line.indexOf('(') ? line.split('(')[0].toLowerCase() : '').trim().replace(/\t/g, '');
  984. if (flag) {
  985. flags.push(flag);
  986. }
  987. });
  988. }
  989. result = flags.join(' ').trim();
  990. if (callback) { callback(result); }
  991. resolve(result);
  992. });
  993. }
  994. if (_darwin) {
  995. exec('sysctl machdep.cpu.features', function (error, stdout) {
  996. if (!error) {
  997. let lines = stdout.toString().split('\n');
  998. if (lines.length > 0 && lines[0].indexOf('machdep.cpu.features:') !== -1) {
  999. result = lines[0].split(':')[1].trim().toLowerCase();
  1000. }
  1001. }
  1002. if (callback) { callback(result); }
  1003. resolve(result);
  1004. });
  1005. }
  1006. if (_sunos) {
  1007. if (callback) { callback(result); }
  1008. resolve(result);
  1009. }
  1010. });
  1011. });
  1012. }
  1013. exports.cpuFlags = cpuFlags;
  1014. // --------------------------
  1015. // CPU Cache
  1016. function cpuCache(callback) {
  1017. return new Promise((resolve) => {
  1018. process.nextTick(() => {
  1019. let result = {
  1020. l1d: -1,
  1021. l1i: -1,
  1022. l2: -1,
  1023. l3: -1,
  1024. };
  1025. if (_linux) {
  1026. try {
  1027. exec('export LC_ALL=C; lscpu; unset LC_ALL', function (error, stdout) {
  1028. if (!error) {
  1029. let lines = stdout.toString().split('\n');
  1030. lines.forEach(function (line) {
  1031. let parts = line.split(':');
  1032. if (parts[0].toUpperCase().indexOf('L1D CACHE') !== -1) {
  1033. result.l1d = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1034. }
  1035. if (parts[0].toUpperCase().indexOf('L1I CACHE') !== -1) {
  1036. result.l1i = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1037. }
  1038. if (parts[0].toUpperCase().indexOf('L2 CACHE') !== -1) {
  1039. result.l2 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1040. }
  1041. if (parts[0].toUpperCase().indexOf('L3 CACHE') !== -1) {
  1042. result.l3 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1043. }
  1044. });
  1045. }
  1046. if (callback) { callback(result); }
  1047. resolve(result);
  1048. });
  1049. } catch (e) {
  1050. if (callback) { callback(result); }
  1051. resolve(result);
  1052. }
  1053. }
  1054. if (_freebsd || _openbsd || _netbsd) {
  1055. exec('export LC_ALL=C; dmidecode -t 7 2>/dev/null; unset LC_ALL', function (error, stdout) {
  1056. let cache = [];
  1057. if (!error) {
  1058. const data = stdout.toString();
  1059. cache = data.split('Cache Information');
  1060. cache.shift();
  1061. }
  1062. for (let i = 0; i < cache.length; i++) {
  1063. const lines = cache[i].split('\n');
  1064. let cacheType = util.getValue(lines, 'Socket Designation').toLowerCase().replace(' ', '-').split('-');
  1065. cacheType = cacheType.length ? cacheType[0] : '';
  1066. const sizeParts = util.getValue(lines, 'Installed Size').split(' ');
  1067. let size = parseInt(sizeParts[0], 10);
  1068. const unit = sizeParts.length > 1 ? sizeParts[1] : 'kb';
  1069. size = size * (unit === 'kb' ? 1024 : (unit === 'mb' ? 1024 * 1024 : (unit === 'gb' ? 1024 * 1024 * 1024 : 1)));
  1070. if (cacheType) {
  1071. if (cacheType === 'l1') {
  1072. result.cache[cacheType + 'd'] = size / 2;
  1073. result.cache[cacheType + 'i'] = size / 2;
  1074. } else {
  1075. result.cache[cacheType] = size;
  1076. }
  1077. }
  1078. }
  1079. if (callback) { callback(result); }
  1080. resolve(result);
  1081. });
  1082. }
  1083. if (_darwin) {
  1084. exec('sysctl hw.l1icachesize hw.l1dcachesize hw.l2cachesize hw.l3cachesize', function (error, stdout) {
  1085. if (!error) {
  1086. let lines = stdout.toString().split('\n');
  1087. lines.forEach(function (line) {
  1088. let parts = line.split(':');
  1089. if (parts[0].toLowerCase().indexOf('hw.l1icachesize') !== -1) {
  1090. result.l1d = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1091. }
  1092. if (parts[0].toLowerCase().indexOf('hw.l1dcachesize') !== -1) {
  1093. result.l1i = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1094. }
  1095. if (parts[0].toLowerCase().indexOf('hw.l2cachesize') !== -1) {
  1096. result.l2 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1097. }
  1098. if (parts[0].toLowerCase().indexOf('hw.l3cachesize') !== -1) {
  1099. result.l3 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
  1100. }
  1101. });
  1102. }
  1103. if (callback) { callback(result); }
  1104. resolve(result);
  1105. });
  1106. }
  1107. if (_sunos) {
  1108. if (callback) { callback(result); }
  1109. resolve(result);
  1110. }
  1111. if (_windows) {
  1112. try {
  1113. util.wmic('cpu get l2cachesize, l3cachesize /value').then((stdout, error) => {
  1114. if (!error) {
  1115. let lines = stdout.split('\r\n');
  1116. result.l1d = 0;
  1117. result.l1i = 0;
  1118. result.l2 = util.getValue(lines, 'l2cachesize', '=');
  1119. result.l3 = util.getValue(lines, 'l3cachesize', '=');
  1120. if (result.l2) { result.l2 = parseInt(result.l2, 10) * 1024; }
  1121. if (result.l3) { result.l3 = parseInt(result.l3, 10) * 1024; }
  1122. }
  1123. util.wmic('path Win32_CacheMemory get CacheType,InstalledSize,Purpose').then((stdout, error) => {
  1124. if (!error) {
  1125. let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0);
  1126. lines.forEach(function (line) {
  1127. if (line !== '') {
  1128. line = line.trim().split(/\s\s+/);
  1129. // L1 Instructions
  1130. if (line[2] === 'L1 Cache' && line[0] === '3') {
  1131. result.l1i = parseInt(line[1], 10);
  1132. }
  1133. // L1 Data
  1134. if (line[2] === 'L1 Cache' && line[0] === '4') {
  1135. result.l1d = parseInt(line[1], 10);
  1136. }
  1137. }
  1138. });
  1139. }
  1140. if (callback) { callback(result); }
  1141. resolve(result);
  1142. });
  1143. });
  1144. } catch (e) {
  1145. if (callback) { callback(result); }
  1146. resolve(result);
  1147. }
  1148. }
  1149. });
  1150. });
  1151. }
  1152. exports.cpuCache = cpuCache;
  1153. // --------------------------
  1154. // CPU - current load - in %
  1155. function getLoad() {
  1156. return new Promise((resolve) => {
  1157. process.nextTick(() => {
  1158. let loads = os.loadavg().map(function (x) { return x / util.cores(); });
  1159. let avgload = parseFloat((Math.max.apply(Math, loads)).toFixed(2));
  1160. let result = {};
  1161. let now = Date.now() - _current_cpu.ms;
  1162. if (now >= 200) {
  1163. _current_cpu.ms = Date.now();
  1164. const cpus = os.cpus();
  1165. let totalUser = 0;
  1166. let totalSystem = 0;
  1167. let totalNice = 0;
  1168. let totalIrq = 0;
  1169. let totalIdle = 0;
  1170. let cores = [];
  1171. _corecount = (cpus && cpus.length) ? cpus.length : 0;
  1172. for (let i = 0; i < _corecount; i++) {
  1173. const cpu = cpus[i].times;
  1174. totalUser += cpu.user;
  1175. totalSystem += cpu.sys;
  1176. totalNice += cpu.nice;
  1177. totalIdle += cpu.idle;
  1178. totalIrq += cpu.irq;
  1179. let tmp_tick = (_cpus && _cpus[i] && _cpus[i].totalTick ? _cpus[i].totalTick : 0);
  1180. let tmp_load = (_cpus && _cpus[i] && _cpus[i].totalLoad ? _cpus[i].totalLoad : 0);
  1181. let tmp_user = (_cpus && _cpus[i] && _cpus[i].user ? _cpus[i].user : 0);
  1182. let tmp_system = (_cpus && _cpus[i] && _cpus[i].sys ? _cpus[i].sys : 0);
  1183. let tmp_nice = (_cpus && _cpus[i] && _cpus[i].nice ? _cpus[i].nice : 0);
  1184. let tmp_idle = (_cpus && _cpus[i] && _cpus[i].idle ? _cpus[i].idle : 0);
  1185. let tmp_irq = (_cpus && _cpus[i] && _cpus[i].irq ? _cpus[i].irq : 0);
  1186. _cpus[i] = cpu;
  1187. _cpus[i].totalTick = _cpus[i].user + _cpus[i].sys + _cpus[i].nice + _cpus[i].irq + _cpus[i].idle;
  1188. _cpus[i].totalLoad = _cpus[i].user + _cpus[i].sys + _cpus[i].nice + _cpus[i].irq;
  1189. _cpus[i].currentTick = _cpus[i].totalTick - tmp_tick;
  1190. _cpus[i].load = (_cpus[i].totalLoad - tmp_load);
  1191. _cpus[i].load_user = (_cpus[i].user - tmp_user);
  1192. _cpus[i].load_system = (_cpus[i].sys - tmp_system);
  1193. _cpus[i].load_nice = (_cpus[i].nice - tmp_nice);
  1194. _cpus[i].load_idle = (_cpus[i].idle - tmp_idle);
  1195. _cpus[i].load_irq = (_cpus[i].irq - tmp_irq);
  1196. cores[i] = {};
  1197. cores[i].load = _cpus[i].load / _cpus[i].currentTick * 100;
  1198. cores[i].load_user = _cpus[i].load_user / _cpus[i].currentTick * 100;
  1199. cores[i].load_system = _cpus[i].load_system / _cpus[i].currentTick * 100;
  1200. cores[i].load_nice = _cpus[i].load_nice / _cpus[i].currentTick * 100;
  1201. cores[i].load_idle = _cpus[i].load_idle / _cpus[i].currentTick * 100;
  1202. cores[i].load_irq = _cpus[i].load_irq / _cpus[i].currentTick * 100;
  1203. cores[i].raw_load = _cpus[i].load;
  1204. cores[i].raw_load_user = _cpus[i].load_user;
  1205. cores[i].raw_load_system = _cpus[i].load_system;
  1206. cores[i].raw_load_nice = _cpus[i].load_nice;
  1207. cores[i].raw_load_idle = _cpus[i].load_idle;
  1208. cores[i].raw_load_irq = _cpus[i].load_irq;
  1209. }
  1210. let totalTick = totalUser + totalSystem + totalNice + totalIrq + totalIdle;
  1211. let totalLoad = totalUser + totalSystem + totalNice + totalIrq;
  1212. let currentTick = totalTick - _current_cpu.tick;
  1213. result = {
  1214. avgload: avgload,
  1215. currentload: (totalLoad - _current_cpu.load) / currentTick * 100,
  1216. currentload_user: (totalUser - _current_cpu.user) / currentTick * 100,
  1217. currentload_system: (totalSystem - _current_cpu.system) / currentTick * 100,
  1218. currentload_nice: (totalNice - _current_cpu.nice) / currentTick * 100,
  1219. currentload_idle: (totalIdle - _current_cpu.idle) / currentTick * 100,
  1220. currentload_irq: (totalIrq - _current_cpu.irq) / currentTick * 100,
  1221. raw_currentload: (totalLoad - _current_cpu.load),
  1222. raw_currentload_user: (totalUser - _current_cpu.user),
  1223. raw_currentload_system: (totalSystem - _current_cpu.system),
  1224. raw_currentload_nice: (totalNice - _current_cpu.nice),
  1225. raw_currentload_idle: (totalIdle - _current_cpu.idle),
  1226. raw_currentload_irq: (totalIrq - _current_cpu.irq),
  1227. cpus: cores
  1228. };
  1229. _current_cpu = {
  1230. user: totalUser,
  1231. nice: totalNice,
  1232. system: totalSystem,
  1233. idle: totalIdle,
  1234. irq: totalIrq,
  1235. tick: totalTick,
  1236. load: totalLoad,
  1237. ms: _current_cpu.ms,
  1238. currentload: result.currentload,
  1239. currentload_user: result.currentload_user,
  1240. currentload_system: result.currentload_system,
  1241. currentload_nice: result.currentload_nice,
  1242. currentload_idle: result.currentload_idle,
  1243. currentload_irq: result.currentload_irq,
  1244. raw_currentload: result.raw_currentload,
  1245. raw_currentload_user: result.raw_currentload_user,
  1246. raw_currentload_system: result.raw_currentload_system,
  1247. raw_currentload_nice: result.raw_currentload_nice,
  1248. raw_currentload_idle: result.raw_currentload_idle,
  1249. raw_currentload_irq: result.raw_currentload_irq,
  1250. };
  1251. } else {
  1252. let cores = [];
  1253. for (let i = 0; i < _corecount; i++) {
  1254. cores[i] = {};
  1255. cores[i].load = _cpus[i].load / _cpus[i].currentTick * 100;
  1256. cores[i].load_user = _cpus[i].load_user / _cpus[i].currentTick * 100;
  1257. cores[i].load_system = _cpus[i].load_system / _cpus[i].currentTick * 100;
  1258. cores[i].load_nice = _cpus[i].load_nice / _cpus[i].currentTick * 100;
  1259. cores[i].load_idle = _cpus[i].load_idle / _cpus[i].currentTick * 100;
  1260. cores[i].load_irq = _cpus[i].load_irq / _cpus[i].currentTick * 100;
  1261. cores[i].raw_load = _cpus[i].load;
  1262. cores[i].raw_load_user = _cpus[i].load_user;
  1263. cores[i].raw_load_system = _cpus[i].load_system;
  1264. cores[i].raw_load_nice = _cpus[i].load_nice;
  1265. cores[i].raw_load_idle = _cpus[i].load_idle;
  1266. cores[i].raw_load_irq = _cpus[i].load_irq;
  1267. }
  1268. result = {
  1269. avgload: avgload,
  1270. currentload: _current_cpu.currentload,
  1271. currentload_user: _current_cpu.currentload_user,
  1272. currentload_system: _current_cpu.currentload_system,
  1273. currentload_nice: _current_cpu.currentload_nice,
  1274. currentload_idle: _current_cpu.currentload_idle,
  1275. currentload_irq: _current_cpu.currentload_irq,
  1276. raw_currentload: _current_cpu.raw_currentload,
  1277. raw_currentload_user: _current_cpu.raw_currentload_user,
  1278. raw_currentload_system: _current_cpu.raw_currentload_system,
  1279. raw_currentload_nice: _current_cpu.raw_currentload_nice,
  1280. raw_currentload_idle: _current_cpu.raw_currentload_idle,
  1281. raw_currentload_irq: _current_cpu.raw_currentload_irq,
  1282. cpus: cores
  1283. };
  1284. }
  1285. resolve(result);
  1286. });
  1287. });
  1288. }
  1289. function currentLoad(callback) {
  1290. return new Promise((resolve) => {
  1291. process.nextTick(() => {
  1292. getLoad().then(result => {
  1293. if (callback) { callback(result); }
  1294. resolve(result);
  1295. });
  1296. });
  1297. });
  1298. }
  1299. exports.currentLoad = currentLoad;
  1300. // --------------------------
  1301. // PS - full load
  1302. // since bootup
  1303. function getFullLoad() {
  1304. return new Promise((resolve) => {
  1305. process.nextTick(() => {
  1306. const cpus = os.cpus();
  1307. let totalUser = 0;
  1308. let totalSystem = 0;
  1309. let totalNice = 0;
  1310. let totalIrq = 0;
  1311. let totalIdle = 0;
  1312. let result = 0;
  1313. if (cpus && cpus.length) {
  1314. for (let i = 0, len = cpus.length; i < len; i++) {
  1315. const cpu = cpus[i].times;
  1316. totalUser += cpu.user;
  1317. totalSystem += cpu.sys;
  1318. totalNice += cpu.nice;
  1319. totalIrq += cpu.irq;
  1320. totalIdle += cpu.idle;
  1321. }
  1322. let totalTicks = totalIdle + totalIrq + totalNice + totalSystem + totalUser;
  1323. result = (totalTicks - totalIdle) / totalTicks * 100.0;
  1324. } else {
  1325. result = 0;
  1326. }
  1327. resolve(result);
  1328. });
  1329. });
  1330. }
  1331. function fullLoad(callback) {
  1332. return new Promise((resolve) => {
  1333. process.nextTick(() => {
  1334. getFullLoad().then(result => {
  1335. if (callback) { callback(result); }
  1336. resolve(result);
  1337. });
  1338. });
  1339. });
  1340. }
  1341. exports.fullLoad = fullLoad;