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 1/8] 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') + }) + }) +}) From 3c71f542a8fa66e6234cc720e9faf52fa3152009 Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 11:10:57 -0700 Subject: [PATCH 2/8] Fixing UT on mac --- spec/api-process-spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/api-process-spec.js b/spec/api-process-spec.js index 2d9ad605a5c1..e53af347a34f 100644 --- a/spec/api-process-spec.js +++ b/spec/api-process-spec.js @@ -12,12 +12,12 @@ describe('process module', function () { 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') + assert.equal(typeof ioCounters.readOperationCount, 'number') + assert.equal(typeof ioCounters.writeOperationCount, 'number') + assert.equal(typeof ioCounters.otherOperationCount, 'number') + assert.equal(typeof ioCounters.readTransferCount, 'number') + assert.equal(typeof ioCounters.writeTransferCount, 'number') + assert.equal(typeof ioCounters.otherTransferCount, 'number') }) }) }) From 8bc4d3f8bd0785cfb5dcc8ee4d87f6905c315731 Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 12:03:05 -0700 Subject: [PATCH 3/8] GetIOCounters is not implemented on mac --- docs/api/process.md | 2 +- spec/api-process-spec.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/api/process.md b/docs/api/process.md index 8e61104d9472..59f80963d81e 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -123,7 +123,7 @@ Returns: * `CPUUsage` [CPUUsage](structures/cpu-usage.md) -### `process.getIOCounters()` +### `process.getIOCounters()` _Windows_ _Linux_ Returns: diff --git a/spec/api-process-spec.js b/spec/api-process-spec.js index e53af347a34f..83a6199a167d 100644 --- a/spec/api-process-spec.js +++ b/spec/api-process-spec.js @@ -11,6 +11,9 @@ describe('process module', function () { describe('process.getIOCounters()', function () { it('returns an io counters object', function () { + if (process.platform !== 'win32') { + return; + } var ioCounters = process.getIOCounters() assert.equal(typeof ioCounters.readOperationCount, 'number') assert.equal(typeof ioCounters.writeOperationCount, 'number') From 656fb593b48f543cbb664010d44828a7ccdbfd39 Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 12:27:47 -0700 Subject: [PATCH 4/8] Fixing lint error --- spec/api-process-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-process-spec.js b/spec/api-process-spec.js index 83a6199a167d..940764fa104b 100644 --- a/spec/api-process-spec.js +++ b/spec/api-process-spec.js @@ -12,7 +12,7 @@ describe('process module', function () { describe('process.getIOCounters()', function () { it('returns an io counters object', function () { if (process.platform !== 'win32') { - return; + return } var ioCounters = process.getIOCounters() assert.equal(typeof ioCounters.readOperationCount, 'number') From 982c5064d86ff043fc4dfb0cc87f873f051f3efc Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 13:15:27 -0700 Subject: [PATCH 5/8] Removing extra bool --- atom/common/api/atom_bindings.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index 90ed750d3e64..a46f3bcf665a 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -41,10 +41,9 @@ 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) { + if (metrics->GetIOCounters(&io_counters)) { dict.Set("readOperationCount", io_counters.ReadOperationCount); dict.Set("writeOperationCount", io_counters.WriteOperationCount); dict.Set("otherOperationCount", io_counters.OtherOperationCount); From 472dad1ffc578b0f95a0c4b52433372c9413ff0a Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 14:15:27 -0700 Subject: [PATCH 6/8] convert var to const --- docs/api/structures/cpu-usage.md | 4 ++-- spec/api-process-spec.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api/structures/cpu-usage.md b/docs/api/structures/cpu-usage.md index bc3455cf071d..b700d4945f0f 100644 --- a/docs/api/structures/cpu-usage.md +++ b/docs/api/structures/cpu-usage.md @@ -1,6 +1,6 @@ # CPUUsage Object -* `percentCPUUsage` number - Percentage of CPU used since the last call to getCPUUsage. +* `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 +* `idleWakeupsPerSecond` Number - The number of average idle cpu wakeups per second since the last call to getCPUUsage. First call returns 0. diff --git a/spec/api-process-spec.js b/spec/api-process-spec.js index 940764fa104b..eab601e56fa8 100644 --- a/spec/api-process-spec.js +++ b/spec/api-process-spec.js @@ -3,7 +3,7 @@ const assert = require('assert') describe('process module', function () { describe('process.getCPUUsage()', function () { it('returns a cpu usage object', function () { - var cpuUsage = process.getCPUUsage() + const cpuUsage = process.getCPUUsage() assert.equal(typeof cpuUsage.percentCPUUsage, 'number') assert.equal(typeof cpuUsage.idleWakeupsPerSecond, 'number') }) @@ -14,7 +14,7 @@ describe('process module', function () { if (process.platform !== 'win32') { return } - var ioCounters = process.getIOCounters() + const ioCounters = process.getIOCounters() assert.equal(typeof ioCounters.readOperationCount, 'number') assert.equal(typeof ioCounters.writeOperationCount, 'number') assert.equal(typeof ioCounters.otherOperationCount, 'number') From 6b51c25820143ca6555f5e29030ae0fb58752525 Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 14:48:37 -0700 Subject: [PATCH 7/8] Exposing cpu & io counters function similar to mem methods --- atom/common/api/atom_bindings.cc | 64 ++++++++++++++++---------------- atom/common/api/atom_bindings.h | 2 + 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index a46f3bcf665a..675ec46a8c2a 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -24,37 +24,6 @@ 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; - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - - if (metrics->GetIOCounters(&io_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) { @@ -205,4 +174,37 @@ v8::Local AtomBindings::GetSystemMemoryInfo(v8::Isolate* isolate, return dict.GetHandle(); } +// static +v8::Local AtomBindings::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(); +} + +// static +v8::Local AtomBindings::GetIOCounters(v8::Isolate* isolate) { + std::unique_ptr metrics( + base::ProcessMetrics::CreateCurrentProcessMetrics()); + base::IoCounters io_counters; + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + + if (metrics->GetIOCounters(&io_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(); +} + } // namespace atom diff --git a/atom/common/api/atom_bindings.h b/atom/common/api/atom_bindings.h index 09561b046b14..1deb50f7d0f2 100644 --- a/atom/common/api/atom_bindings.h +++ b/atom/common/api/atom_bindings.h @@ -37,6 +37,8 @@ class AtomBindings { static v8::Local GetProcessMemoryInfo(v8::Isolate* isolate); static v8::Local GetSystemMemoryInfo(v8::Isolate* isolate, mate::Arguments* args); + static v8::Local GetCPUUsage(v8::Isolate* isolate); + static v8::Local GetIOCounters(v8::Isolate* isolate); private: void ActivateUVLoop(v8::Isolate* isolate); From 07d8dfaa53f8c4b2d7f9e46ca414a8ec798be05e Mon Sep 17 00:00:00 2001 From: Hari Krishna Reddy Juturu Date: Thu, 4 May 2017 14:50:06 -0700 Subject: [PATCH 8/8] Fixing UT --- spec/api-process-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-process-spec.js b/spec/api-process-spec.js index eab601e56fa8..5f4ad1730bce 100644 --- a/spec/api-process-spec.js +++ b/spec/api-process-spec.js @@ -11,7 +11,7 @@ describe('process module', function () { describe('process.getIOCounters()', function () { it('returns an io counters object', function () { - if (process.platform !== 'win32') { + if (process.platform === 'darwin') { return } const ioCounters = process.getIOCounters()