From 74d98bff67bdcdb3147316f821ddc6347a032ad9 Mon Sep 17 00:00:00 2001 From: theanarkh Date: Mon, 31 Oct 2022 20:14:35 +0800 Subject: [PATCH] report: add more memory info --- doc/api/report.md | 10 +++++++--- src/node_report.cc | 26 +++++++++++++++++++++++--- test/common/report.js | 22 ++++++++++++++++------ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/doc/api/report.md b/doc/api/report.md index 507434f6c63868..fc005d6e0e8dda 100644 --- a/doc/api/report.md +++ b/doc/api/report.md @@ -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", @@ -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 diff --git a/src/node_report.cc b/src/node_report.cc index a867a4c38caa72..a6622b49a0e0ba 100644 --- a/src/node_report.cc +++ b/src/node_report.cc @@ -23,7 +23,7 @@ #include #include -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; @@ -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) { @@ -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); diff --git a/test/common/report.js b/test/common/report.js index fd8642fb4f084e..12bf30f4d0a499 100644 --- a/test/common/report.js +++ b/test/common/report.js @@ -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); @@ -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));