From 682105538a8393dae7d3e6abe6d92757df194fc3 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Wed, 12 Jun 2019 07:51:15 -0700 Subject: [PATCH] report: add cpu info to report output The report shows CPU consumption %, but without the number of CPU cores, a consumer cannot tell if the percent (given across all cores) is actually problematic. E.g., 100% on one CPU is a problem, but 100% on four CPUs is not necessarily. This change adds CPU information (similar to `os.cpus()`) to the report output. Extra info besides the count is also provided as to avoid future breaking changes in the eventuality that someone needs it; changing the datatype of `header.cpus` would be breaking. PR-URL: https://github.com/nodejs/node/pull/28188 Refs: https://github.com/nodejs/diagnostics/issues/307 Reviewed-By: Sam Roberts Reviewed-By: Gireesh Punathil Reviewed-By: Richard Lau Reviewed-By: Ruben Bridgewater Reviewed-By: Trivikram Kamat Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: Rich Trott Reviewed-By: James M Snell --- doc/api/report.md | 20 ++++++++++++++++++++ src/node_report.cc | 25 +++++++++++++++++++++++++ test/common/report.js | 14 ++++++++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/doc/api/report.md b/doc/api/report.md index 40e3050ee4d24d..9d773f25ee636f 100644 --- a/doc/api/report.md +++ b/doc/api/report.md @@ -62,6 +62,26 @@ is provided below for reference. "osRelease": "3.10.0-862.el7.x86_64", "osVersion": "#1 SMP Wed Mar 21 18:14:51 EDT 2018", "osMachine": "x86_64", + "osCpus": [ + { + "model": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz", + "speed": 2700, + "user": 88902660, + "nice": 0, + "sys": 50902570, + "idle": 241732220, + "irq": 0 + }, + { + "model": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz", + "speed": 2700, + "user": 88902660, + "nice": 0, + "sys": 50902570, + "idle": 241732220, + "irq": 0 + } + ], "host": "test_machine" }, "javascriptStack": { diff --git a/src/node_report.cc b/src/node_report.cc index 18607656256d51..b448ffd099bf27 100644 --- a/src/node_report.cc +++ b/src/node_report.cc @@ -65,6 +65,7 @@ static void PrintSystemInformation(JSONWriter* writer); static void PrintLoadedLibraries(JSONWriter* writer); static void PrintComponentVersions(JSONWriter* writer); static void PrintRelease(JSONWriter* writer); +static void PrintCpuInfo(JSONWriter* writer); // External function to trigger a report, writing to file. // The 'name' parameter is in/out: an input filename is used @@ -315,6 +316,8 @@ static void PrintVersionInformation(JSONWriter* writer) { writer->json_keyvalue("osMachine", os_info.machine); } + PrintCpuInfo(writer); + char host[UV_MAXHOSTNAMESIZE]; size_t host_size = sizeof(host); @@ -322,6 +325,28 @@ static void PrintVersionInformation(JSONWriter* writer) { writer->json_keyvalue("host", host); } +// Report CPU info +static void PrintCpuInfo(JSONWriter* writer) { + uv_cpu_info_t* cpu_info; + int count; + if (uv_cpu_info(&cpu_info, &count) == 0) { + writer->json_arraystart("cpus"); + for (int i = 0; i < count; i++) { + writer->json_start(); + writer->json_keyvalue("model", cpu_info->model); + writer->json_keyvalue("speed", cpu_info->speed); + writer->json_keyvalue("user", cpu_info->cpu_times.user); + writer->json_keyvalue("nice", cpu_info->cpu_times.nice); + writer->json_keyvalue("sys", cpu_info->cpu_times.sys); + writer->json_keyvalue("idle", cpu_info->cpu_times.idle); + writer->json_keyvalue("irq", cpu_info->cpu_times.irq); + writer->json_end(); + } + writer->json_arrayend(); + uv_free_cpu_info(cpu_info, count); + } +} + // Report the JavaScript stack. static void PrintJavaScriptStack(JSONWriter* writer, Isolate* isolate, diff --git a/test/common/report.js b/test/common/report.js index 163daf286ef7c9..f415b66dccacfa 100644 --- a/test/common/report.js +++ b/test/common/report.js @@ -62,8 +62,8 @@ function _validateContent(data) { 'dumpEventTimeStamp', 'processId', 'commandLine', 'nodejsVersion', 'wordSize', 'arch', 'platform', 'componentVersions', 'release', 'osName', 'osRelease', - 'osVersion', 'osMachine', 'host', 'glibcVersionRuntime', - 'glibcVersionCompiler', 'cwd']; + 'osVersion', 'osMachine', 'cpus', 'host', + 'glibcVersionRuntime', 'glibcVersionCompiler', 'cwd']; checkForUnknownFields(header, headerFields); assert.strictEqual(typeof header.event, 'string'); assert.strictEqual(typeof header.trigger, 'string'); @@ -87,6 +87,16 @@ function _validateContent(data) { assert.strictEqual(header.osRelease, os.release()); assert.strictEqual(typeof header.osVersion, 'string'); assert.strictEqual(typeof header.osMachine, 'string'); + assert(Array.isArray(header.cpus)); + header.cpus.forEach((cpu) => { + assert.strictEqual(typeof cpu.model, 'string'); + assert.strictEqual(typeof cpu.speed, 'number'); + assert.strictEqual(typeof cpu.user, 'number'); + assert.strictEqual(typeof cpu.nice, 'number'); + assert.strictEqual(typeof cpu.sys, 'number'); + assert.strictEqual(typeof cpu.idle, 'number'); + assert.strictEqual(typeof cpu.irq, 'number'); + }); assert.strictEqual(header.host, os.hostname()); // Verify the format of the javascriptStack section.