node.js 通过 NodeJS 获取/查看内存和 CPU 使用率

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36816181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:08:54  来源:igfitidea点击:

Get/View Memory & CPU usage via NodeJS

node.jsnpm

提问by C0NFUS3D

I see there are several node packages that allow you to look up a specific process's usage, such as https://www.npmjs.com/package/usage

我看到有几个节点包可以让您查找特定进程的使用情况,例如https://www.npmjs.com/package/usage

I am trying to get the overall sever usage/stats (CPU and Memory), not just one specific process or another. Maybe even disk space usage.

我正在尝试获取整体服务器使用情况/统计信息(CPU 和内存),而不仅仅是一个或另一个特定进程。甚至可能使用磁盘空间。

I am currently unable to find anything like this, is this possible?

我目前无法找到这样的东西,这可能吗?

回答by piscator

The native module oscan give you some memory and cpu usage statistics.

本机模块os可以为您提供一些内存和 cpu 使用情况统计信息。

var os = require('os');

console.log(os.cpus());
console.log(os.totalmem());
console.log(os.freemem())

The cpus() function gives you an average, but you can calculate the current usage by using a formula and an interval, as mentioned in thisanswer.

cpus() 函数为您提供平均值,但您可以使用公式和间隔来计算当前使用情况,如答案中所述。

There is also a package that does this for you, called os-utils.

还有一个包可以为您执行此操作,称为os-utils

Taken from the example on github:

取自github上的示例:

var os = require('os-utils');

os.cpuUsage(function(v){
    console.log( 'CPU Usage (%): ' + v );
});

For information about the disk you can use diskspace

有关磁盘的信息,您可以使用diskspace

回答by Rajiv Sharma

Check node-os-utils

检查node-os-utils

  • CPU average usage
  • Free and used drive space
  • Free and used memory space
  • Operating System
  • All processes running
  • TTY/SSH opened
  • Total opened files
  • Network speed (input and output)
  • CPU平均使用率
  • 可用和已用驱动器空间
  • 可用和已用内存空间
  • 操作系统
  • 正在运行的所有进程
  • TTY/SSH 打开
  • 打开的文件总数
  • 网络速度(输入和输出)
var osu = require('node-os-utils')

var cpu = osu.cpu

cpu.usage()
  .then(info => {
    console.log(info)
  })
var osu = require('node-os-utils')

var cpu = osu.cpu

cpu.usage()
  .then(info => {
    console.log(info)
  })

回答by Shane Gannon

You can also use process.cpuUsage()to return the system and user cpu time in microseconds. It can also calculate the difference to a previous call.

您还可以使用process.cpuUsage()以微秒为单位返回系统和用户 cpu 时间。它还可以计算与先前调用的差异。

https://nodejs.org/api/process.html#process_process_cpuusage_previousvalue

https://nodejs.org/api/process.html#process_process_cpuusage_previousvalue

回答by Sebastian Hildebrandt

The most mature npm package currently is systeminformation. This package is a collection of 40+ functions to retrieve detailed hardware, system and OS information. See detailed documentation here: https://systeminformation.io

目前最成熟的 npm 包是systeminformation. 这个包是 40 多个函数的集合,用于检索详细的硬件、系统和操作系统信息。在此处查看详细文档:https: //systeminformation.io

Here you get i.e. detailed information about

在这里你可以得到 ie 的详细信息

  • hardware information (CPU, memory layout, disks, ...)
  • system information (baseboard, BIOS, chassis, ...)
  • cpu usage
  • current load
  • process information
  • cpu temperature
  • memory usage
  • disk usage (size, disk IO, ...)
  • graphics
  • OS information
  • network information (interfaces and network stats)
  • battery status
  • wifi networks
  • running services
  • virtual box information
  • docker information (containers and container stats)
  • 硬件信息(CPU、内存布局、磁盘等)
  • 系统信息(基板、BIOS、机箱等)
  • CPU使用率
  • 当前负载
  • 处理信息
  • cpu温度
  • 内存使用情况
  • 磁盘使用情况(大小、磁盘 IO 等)
  • 图形
  • 操作系统信息
  • 网络信息(接口和网络统计信息)
  • 电池状态
  • 无线网络
  • 运行服务
  • 虚拟盒子信息
  • docker 信息(容器和容器统计信息)

回答by Sebastian Hildebrandt

Of course it is possible. But you'll need a C++ native module to do that. And keep in mind that every OS has their own way of querying system resource usage.

当然这是可能的。但是您需要一个 C++ 本机模块来做到这一点。请记住,每个操作系统都有自己的查询系统资源使用情况的方式。

For example, if you're on Windows (which might be what you're looking for since usagedoesn't support Windows), you could do something like

例如,如果你在 Windows 上(这可能是你正在寻找的,因为usage它不支持 Windows),你可以做类似的事情

performance.cpp

性能.cpp

#include <node.h>
#include "performance_algorithm.hpp"

using namespace v8;

void InitAll(Handle<Object> exports) {
    PerformanceAlgorithm::Initialize();
    PerformanceAlgorithm::RegisterMethod(exports);
}

NODE_MODULE(Performance, InitAll)

performance_algorithm.cpp

性能算法.cpp

#include <algorithm>

#include "baton.hpp"
#include "structs.hpp"
#include "performance_algorithm.hpp"

void PerformanceAlgorithm::Initialize() {
    PdhOpenQuery(NULL, NULL, &cpuQuery);
    PdhAddCounter(cpuQuery, "\Processor(_Total)\% Processor Time", NULL, &cpuTotal);
    PdhCollectQueryData(cpuQuery);
}

void PerformanceAlgorithm::RegisterMethod(Handle<Object> exports) {
    NODE_SET_METHOD(exports, "getPerformanceData", PerformanceAlgorithm::GetPerformanceDataAsync);
}

void PerformanceAlgorithm::GetPerformanceDataAsync(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    if (args.Length() != 1) {
        isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong number of arguments")));
    } else {
        if (!args[0]->IsFunction()) {
            isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong arguments type")));
        } else {
            Local<Function> callbackFunction = Local<Function>::Cast(args[0]);

            Baton<string, PerformanceData>* baton = new Baton<string, PerformanceData>();
            baton->request.data = baton;
            baton->callbackFunction.Reset(isolate, callbackFunction);

            uv_queue_work(uv_default_loop(), &baton->request, PerformanceAlgorithm::GetPerformanceDataWork, PerformanceAlgorithm::GetPerformanceDataAsyncAfter);
        }
    }
}

void PerformanceAlgorithm::GetPerformanceDataWork(uv_work_t* request) {
    Baton<string, PerformanceData>* baton = static_cast<Baton<string, PerformanceData>*>(request->data);

    baton->result.memory_info.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&baton->result.memory_info);

    PDH_FMT_COUNTERVALUE counterVal;
    PdhCollectQueryData(cpuQuery);
    PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);
    baton->result.cpu_usage = counterVal.doubleValue;

    DWORD processIDs[1024], bytesReturned;
    EnumProcesses(processIDs, sizeof(processIDs), &bytesReturned);

    DWORD numberOfProcesses = bytesReturned / sizeof(DWORD);
    for (int i = 0; i < numberOfProcesses; i++) {
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]);

        HMODULE hMods[1024];
        DWORD cbNeeded;
        if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
            for (int j = 0; j < (cbNeeded / sizeof(HMODULE)); j++) {
                TCHAR szModName[MAX_PATH];
                GetModuleFileNameEx(hProcess, hMods[j], szModName, sizeof(szModName) / sizeof(TCHAR));

                ProcessInfo info;
                info.process_id = processIDs[i];
                info.path = string(szModName);

                baton->result.processes.push_back(info);

                break;
            }
        }

        CloseHandle(hProcess);
    }

    sort(baton->result.processes.begin(), baton->result.processes.end(), [](ProcessInfo a, ProcessInfo b) -> bool {
        return a.process_id < b.process_id;
    });

    GetPerformanceInfo(&baton->result.performance_info, sizeof(PERFORMACE_INFORMATION));
}

void PerformanceAlgorithm::GetPerformanceDataAsyncAfter(uv_work_t* request, int status) {
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);
    EscapableHandleScope escapableHandleScope(isolate);

    Baton<string, PerformanceData>* baton = static_cast<Baton<string, PerformanceData>*>(request->data);
    Local<Function> callbackFunction = Local<Function>::New(isolate, baton->callbackFunction);

    Local<Object> returnValue = Object::New(isolate);
    returnValue->Set(String::NewFromUtf8(isolate, "cpu_usage"), Number::New(isolate, baton->result.cpu_usage));
    returnValue->Set(String::NewFromUtf8(isolate, "ram_usage"), Number::New(isolate, baton->result.memory_info.dwMemoryLoad));
    returnValue->Set(String::NewFromUtf8(isolate, "total_physical_memory"), Number::New(isolate, baton->result.memory_info.ullTotalPhys));
    returnValue->Set(String::NewFromUtf8(isolate, "available_physical_memory"), Number::New(isolate, baton->result.memory_info.ullAvailPhys));
    returnValue->Set(String::NewFromUtf8(isolate, "total_page_file"), Number::New(isolate, baton->result.memory_info.ullTotalPageFile));
    returnValue->Set(String::NewFromUtf8(isolate, "available_page_file"), Number::New(isolate, baton->result.memory_info.ullAvailPageFile));
    returnValue->Set(String::NewFromUtf8(isolate, "total_virtual"), Number::New(isolate, baton->result.memory_info.ullTotalVirtual));
    returnValue->Set(String::NewFromUtf8(isolate, "available_virtual"), Number::New(isolate, baton->result.memory_info.ullAvailVirtual));

    Local<Array> processes = Array::New(isolate, baton->result.processes.size());
    for (int i = 0; i < baton->result.processes.size(); i++) {
        Local<Object> processInfo = Object::New(isolate);
        processInfo->Set(String::NewFromUtf8(isolate, "process_id"), Number::New(isolate, baton->result.processes[i].process_id));
        processInfo->Set(String::NewFromUtf8(isolate, "path"), String::NewFromUtf8(isolate, baton->result.processes[i].path.c_str()));

        processes->Set(i, processInfo);
    }
    returnValue->Set(String::NewFromUtf8(isolate, "running_processes"), processes);

    const unsigned int argc = 1;
    Handle<Value> argv[argc] = { escapableHandleScope.Escape(returnValue) };
    callbackFunction->Call(isolate->GetCurrentContext()->Global(), argc, argv);

    baton->callbackFunction.Reset();
    delete baton;
}