From 8a5aa04756de22a7fcbd407d3fa38ae8e392272e Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 10:49:01 -0700 Subject: [PATCH] Adding CPU and I/O metrics to process module --- atom/common/api/atom_bindings.cc | 35 ++++++++++++++++++++++++++++++ docs/api/process.md | 12 ++++++++++ docs/api/structures/cpu-usage.md | 6 +++++ docs/api/structures/io-counters.md | 8 +++++++ spec/api-process-spec.js | 23 ++++++++++++++++++++ 5 files changed, 84 insertions(+) create mode 100644 docs/api/structures/cpu-usage.md create mode 100644 docs/api/structures/io-counters.md create mode 100644 spec/api-process-spec.js diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index 9d8c15ff4faf..90ed750d3e64 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -14,6 +14,7 @@ #include "atom/common/node_includes.h" #include "base/logging.h" #include "base/process/process_metrics.h" +#include "base/sys_info.h" #include "native_mate/dictionary.h" namespace atom { @@ -23,6 +24,38 @@ namespace { // Dummy class type that used for crashing the program. struct DummyClass { bool crash; }; +v8::Local GetCPUUsage(v8::Isolate* isolate) { + std::unique_ptr metrics( + base::ProcessMetrics::CreateCurrentProcessMetrics()); + + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + int processor_count = base::SysInfo::NumberOfProcessors(); + dict.Set("percentCPUUsage", + metrics->GetPlatformIndependentCPUUsage() / processor_count); + dict.Set("idleWakeupsPerSecond", metrics->GetIdleWakeupsPerSecond()); + + return dict.GetHandle(); +} + +v8::Local GetIOCounters(v8::Isolate* isolate) { + std::unique_ptr metrics( + base::ProcessMetrics::CreateCurrentProcessMetrics()); + base::IoCounters io_counters; + const bool got_counters = metrics->GetIOCounters(&io_counters); + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + + if (got_counters) { + dict.Set("readOperationCount", io_counters.ReadOperationCount); + dict.Set("writeOperationCount", io_counters.WriteOperationCount); + dict.Set("otherOperationCount", io_counters.OtherOperationCount); + dict.Set("readTransferCount", io_counters.ReadTransferCount); + dict.Set("writeTransferCount", io_counters.WriteTransferCount); + dict.Set("otherTransferCount", io_counters.OtherTransferCount); + } + + return dict.GetHandle(); +} + // Called when there is a fatal error in V8, we just crash the process here so // we can get the stack trace. void FatalErrorCallback(const char* location, const char* message) { @@ -52,6 +85,8 @@ void AtomBindings::BindTo(v8::Isolate* isolate, dict.SetMethod("log", &Log); dict.SetMethod("getProcessMemoryInfo", &GetProcessMemoryInfo); dict.SetMethod("getSystemMemoryInfo", &GetSystemMemoryInfo); + dict.SetMethod("getCPUUsage", &GetCPUUsage); + dict.SetMethod("getIOCounters", &GetIOCounters); #if defined(OS_POSIX) dict.SetMethod("setFdLimit", &base::SetFdLimit); #endif diff --git a/docs/api/process.md b/docs/api/process.md index 84320ca98bb0..8e61104d9472 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -116,3 +116,15 @@ Returns `Object`: Returns an object giving memory usage statistics about the entire system. Note that all statistics are reported in Kilobytes. + +### `process.getCPUUsage()` + +Returns: + +* `CPUUsage` [CPUUsage](structures/cpu-usage.md) + +### `process.getIOCounters()` + +Returns: + +* `IOCounters` [IOCounters](structures/io-counters.md) \ No newline at end of file diff --git a/docs/api/structures/cpu-usage.md b/docs/api/structures/cpu-usage.md new file mode 100644 index 000000000000..bc3455cf071d --- /dev/null +++ b/docs/api/structures/cpu-usage.md @@ -0,0 +1,6 @@ +# CPUUsage Object + +* `percentCPUUsage` number - Percentage of CPU used since the last call to getCPUUsage. + First call returns 0. +* `idleWakeupsPerSecond` number - The number of average idle cpu wakeups per second + since the last call to getCPUUsage. First call returns 0. diff --git a/docs/api/structures/io-counters.md b/docs/api/structures/io-counters.md new file mode 100644 index 000000000000..62ad39a90b09 --- /dev/null +++ b/docs/api/structures/io-counters.md @@ -0,0 +1,8 @@ +# IOCounters Object + +* `readOperationCount` Number - The number of I/O read operations. +* `writeOperationCount` Number - The number of I/O write operations. +* `otherOperationCount` Number - Then number of I/O other operations. +* `readTransferCount` Number - The number of I/O read transfers. +* `writeTransferCount` Number - The number of I/O write transfers. +* `otherTransferCount` Number - Then number of I/O other transfers. diff --git a/spec/api-process-spec.js b/spec/api-process-spec.js new file mode 100644 index 000000000000..2d9ad605a5c1 --- /dev/null +++ b/spec/api-process-spec.js @@ -0,0 +1,23 @@ +const assert = require('assert') + +describe('process module', function () { + describe('process.getCPUUsage()', function () { + it('returns a cpu usage object', function () { + var cpuUsage = process.getCPUUsage() + assert.equal(typeof cpuUsage.percentCPUUsage, 'number') + assert.equal(typeof cpuUsage.idleWakeupsPerSecond, 'number') + }) + }) + + describe('process.getIOCounters()', function () { + it('returns an io counters object', function () { + var ioCounters = process.getIOCounters() + assert.ok(ioCounters.readOperationCount > 0, 'read operation count not > 0') + assert.ok(ioCounters.writeOperationCount > 0, 'write operation count not > 0') + assert.ok(ioCounters.otherOperationCount > 0, 'other operation count not > 0') + assert.ok(ioCounters.readTransferCount > 0, 'read transfer count not > 0') + assert.ok(ioCounters.writeTransferCount > 0, 'write transfer count not > 0') + assert.ok(ioCounters.otherTransferCount > 0, 'other transfer count not > 0') + }) + }) +})