Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report: add more memory info #45254

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions doc/api/report.md
Expand Up @@ -23,7 +23,7 @@ is provided below for reference.
```json
{
"header": {
"reportVersion": 1,
"reportVersion": 3,
"event": "exception",
"trigger": "Exception",
"filename": "report.20181221.005011.8974.0.001.json",
Expand Down Expand Up @@ -198,13 +198,17 @@ is provided below for reference.
}
},
"resourceUsage": {
"rss": 45768704,
"rss": "35766272",
"free_memory": "1598337024",
"total_memory": "17179869184",
"available_memory": "1598337024",
"maxRss": "36624662528",
"constrained_memory": "36624662528",
"userCpuSeconds": 0.040072,
"kernelCpuSeconds": 0.016029,
"cpuConsumptionPercent": 5.6101,
"userCpuConsumptionPercent": 4.0072,
"kernelCpuConsumptionPercent": 1.6029,
"maxRss": 45768704,
"pageFaults": {
"IORequired": 0,
"IONotRequired": 4610
Expand Down
26 changes: 23 additions & 3 deletions src/node_report.cc
Expand Up @@ -23,7 +23,7 @@
#include <cwctype>
#include <fstream>

constexpr int NODE_REPORT_VERSION = 2;
constexpr int NODE_REPORT_VERSION = 3;
constexpr int NANOS_PER_SEC = 1000 * 1000 * 1000;
constexpr double SEC_PER_MICROS = 1e-6;
constexpr int MAX_FRAME_COUNT = 10;
Expand Down Expand Up @@ -628,10 +628,30 @@ static void PrintResourceUsage(JSONWriter* writer) {
uv_rusage_t rusage;
writer->json_objectstart("resourceUsage");

uint64_t free_memory = uv_get_free_memory();
uint64_t total_memory = uv_get_total_memory();

writer->json_keyvalue("free_memory", std::to_string(free_memory));
writer->json_keyvalue("total_memory", std::to_string(total_memory));

size_t rss;
int err = uv_resident_set_memory(&rss);
if (!err) {
writer->json_keyvalue("rss", rss);
writer->json_keyvalue("rss", std::to_string(rss));
}

uint64_t constrained_memory = uv_get_constrained_memory();
if (constrained_memory) {
writer->json_keyvalue("constrained_memory",
std::to_string(constrained_memory));
}

// See GuessMemoryAvailableToTheProcess
if (!err && constrained_memory && constrained_memory >= rss) {
uint64_t available_memory = constrained_memory - rss;
writer->json_keyvalue("available_memory", std::to_string(available_memory));
} else {
writer->json_keyvalue("available_memory", std::to_string(free_memory));
}

if (uv_getrusage(&rusage) == 0) {
Expand All @@ -648,7 +668,7 @@ static void PrintResourceUsage(JSONWriter* writer) {
writer->json_keyvalue("cpuConsumptionPercent", cpu_percentage);
writer->json_keyvalue("userCpuConsumptionPercent", user_cpu_percentage);
writer->json_keyvalue("kernelCpuConsumptionPercent", kernel_cpu_percentage);
writer->json_keyvalue("maxRss", rusage.ru_maxrss * 1024);
writer->json_keyvalue("maxRss", std::to_string(rusage.ru_maxrss * 1024));
writer->json_objectstart("pageFaults");
writer->json_keyvalue("IORequired", rusage.ru_majflt);
writer->json_keyvalue("IONotRequired", rusage.ru_minflt);
Expand Down
22 changes: 16 additions & 6 deletions test/common/report.js
Expand Up @@ -105,7 +105,7 @@ function _validateContent(report, fields = []) {
'glibcVersionRuntime', 'glibcVersionCompiler', 'cwd',
'reportVersion', 'networkInterfaces', 'threadId'];
checkForUnknownFields(header, headerFields);
assert.strictEqual(header.reportVersion, 2); // Increment as needed.
assert.strictEqual(header.reportVersion, 3); // Increment as needed.
assert.strictEqual(typeof header.event, 'string');
assert.strictEqual(typeof header.trigger, 'string');
assert(typeof header.filename === 'string' || header.filename === null);
Expand Down Expand Up @@ -232,19 +232,29 @@ function _validateContent(report, fields = []) {
}

// Verify the format of the resourceUsage section.
const usage = report.resourceUsage;
const usage = { ...report.resourceUsage };
// Delete it, otherwise checkForUnknownFields will throw error
delete usage.constrained_memory;
const resourceUsageFields = ['userCpuSeconds', 'kernelCpuSeconds',
'cpuConsumptionPercent', 'userCpuConsumptionPercent',
'kernelCpuConsumptionPercent', 'rss', 'maxRss',
'pageFaults', 'fsActivity'];
'kernelCpuConsumptionPercent',
'maxRss', 'rss', 'free_memory', 'total_memory',
'available_memory', 'pageFaults', 'fsActivity'];
checkForUnknownFields(usage, resourceUsageFields);
assert.strictEqual(typeof usage.userCpuSeconds, 'number');
assert.strictEqual(typeof usage.kernelCpuSeconds, 'number');
assert.strictEqual(typeof usage.cpuConsumptionPercent, 'number');
assert.strictEqual(typeof usage.userCpuConsumptionPercent, 'number');
assert.strictEqual(typeof usage.kernelCpuConsumptionPercent, 'number');
assert(Number.isSafeInteger(usage.rss));
assert(Number.isSafeInteger(usage.maxRss));
assert(typeof usage.rss, 'string');
assert(typeof usage.maxRss, 'string');
assert(typeof usage.free_memory, 'string');
assert(typeof usage.total_memory, 'string');
assert(typeof usage.available_memory, 'string');
// This field may not exsit
if (report.resourceUsage.constrained_memory) {
assert(typeof report.resourceUsage.constrained_memory, 'string');
}
assert(typeof usage.pageFaults === 'object' && usage.pageFaults !== null);
checkForUnknownFields(usage.pageFaults, ['IORequired', 'IONotRequired']);
assert(Number.isSafeInteger(usage.pageFaults.IORequired));
Expand Down