UNPKG

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