如何用 node.js 獲取目標進程的 CPU 占用率


前言

本腳本僅僅在 linux 上方便使用,請大家注意,先不廢話,上腳本。

代碼

/*
測試程序
while( true ){
    a = exports.getProcessCPUUsage( [ 2882, 10388 ], oldProcessTock )
    oldProcessTock = a.processTick;
    // rate += parseFloat( a.rate );
    count++;
    if( count % 100000 == 0 ){
        console.log( `${count} ${rate}` )
        console.log( Date.now() )
        count = 0;
        rate = 0;
    }
}

平均每秒該方法可以操作
    21579.628830384117 次
測試平台
    Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz

*/

var fs = require( 'fs' );
var os = require( 'os' );

var CPUCoreNumbers = os.cpus().length;

var CPUTikHistory = null;
exports.getProcessCPUUsage = ( pid, oldProcessTick, sysTickPerSec ) => {
    // let ProcessStat = fs.readFileSync( `/proc/${process.pid}/stat`, 'utf8' );

    var ProcessTickSum = 0;
    if( Array.isArray( pid ) ){
        pid.forEach( p => {
            let ProcessStat = fs.readFileSync( `/proc/${p}/stat`, 'utf8' );
            let ProcessStatArr = ProcessStat.match( /(\w+)+/g )
            if( ProcessStatArr == null ) return null;
            ProcessTickSum += parseInt( ProcessStatArr[13] ) + parseInt( ProcessStatArr[14] );
        } )
    }else{
        let ProcessStat = fs.readFileSync( `/proc/${pid}/stat`, 'utf8' );
        let ProcessStatArr = ProcessStat.match( /(\w+)+/g )
        if( ProcessStatArr == null ) return null;
        ProcessTickSum = parseInt( ProcessStatArr[13] ) + parseInt( ProcessStatArr[14] );
    }

    let TikSum = 0;
    if( sysTickPerSec == null ){
        let CPUStat = fs.readFileSync( '/proc/stat', 'utf8' );
        let MatchLine = CPUStat.match(/(.*)\n/);
        if( MatchLine == null ){
            console.error( "This function not match this machain, please take care" );
            process.exit();
        }
        let CPULineArr = MatchLine[1].match( /(\w+)+/g );
        // console.log( CPULineArr )
        if( CPULineArr[0] != 'cpu' ){
            console.error( "This function not match this machain, please take care" );
            process.exit();
        }
        CPULineArr.forEach( (num) => {
            let i = parseInt( num );
            if( isNaN( i ) ) return;
            TikSum += parseInt(num);
        } )
        if( CPUTikHistory == null ){
            CPUTikHistory = TikSum;
        }
    }

    if( ( oldProcessTick == null ) || ( oldProcessTick == 0 ) ){
        if( sysTickPerSec == null ){
            return {
                rate: 0.00,
                processTick: ProcessTickSum,
                sysTick: TikSum,
            }
        }else{
            return {
                rate: 0.00,
                processTick: ProcessTickSum,
            }
        }
    }

    if( sysTickPerSec == null ){
        DiffSysTick = TikSum - CPUTikHistory;
        CPUTikHistory = TikSum;
        if( DiffSysTick == 0 ){
            return {
                rate: 0,
                processTick: ProcessTickSum,
                sysTick: TikSum,
            }
        }
        let rate = ( ProcessTickSum - oldProcessTick )*100/DiffSysTick*CPUCoreNumbers
        return {
            rate: rate.toFixed(2),
            processTick: ProcessTickSum,
            sysTick: TikSum,
        }
    }else{
        let rate = ( ProcessTickSum - oldProcessTick )*100/sysTickPerSec*CPUCoreNumbers;

        return {
            rate: rate.toFixed(2),
            processTick: ProcessTickSum,
        }
    }
}

//==============================================================================
// let oldProcessTock = 0;
// setInterval( ()=>{
//
//     a = exports.getProcessCPUUsage( [ 2882, 10388 ], oldProcessTock )
//     console.log( a );
//     oldProcessTock = a.processTick;
//
// }, 1000 );

說明

getProcessCPUUsage 函數接受三個參數,前兩個是必選的,第三個是可選的
pid
    代表想查詢程序的 pid, 如果想查詢自己的,可用 proceess.pid 獲取,
    如果想合並查詢幾個進程共同的 CPU 占用率,可以用數組包含各個進程的 PID

oldProcessTick
    為上一次的進程的 Tick, 如果是第一次則設置為 0,
    在運行完本函數后會返回當下指定進程的所有 Tick, 之后可以下一次使用

sysTickPerSec
    如果你知道當前系統的一秒內的固定 Tick,你可以從這個參數傳進來,這樣減少該函數的運算所需的資源
    如果你不知道,不設置即可,該函數會自動算出兩次調用該函數時間段內的總 Tick

返回有三個參數
rate
    CPU 占用率,單位為 xx.xx%, 保留兩位小樹

processTick
    指定進程當前 Tick 之和

sysTick
    當前系統的總 Tick
    當你指定 sysTickPerSec 則無此字段

注意
1. 這里返回的 CPU 占用率是只兩次調用之間的 CPU 占用率,如果你不是嚴格的按照每秒調用一次該函數, CPU 占用率會和 Top 顯示的不一樣。
2. 如果你的硬件平台不只一個 CPU,而且你是按照每秒調用一次,而且你想獲取進程的 CPU 占用率特別高,那么此時此處的 CPU 占用率會超過 100%


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM