report: support RUSAGE_SELF stats on Windows
This commit adds support for the resourceUsage report section on Windows by using uv_getrusage() instead of getrusage(). PR-URL: https://github.com/nodejs/node/pull/26406 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
e630569883
commit
84ebaaa339
@ -81,9 +81,7 @@ static void PrintJavaScriptStack(JSONWriter* writer,
|
|||||||
Local<String> stackstr,
|
Local<String> stackstr,
|
||||||
const char* trigger);
|
const char* trigger);
|
||||||
static void PrintNativeStack(JSONWriter* writer);
|
static void PrintNativeStack(JSONWriter* writer);
|
||||||
#ifndef _WIN32
|
|
||||||
static void PrintResourceUsage(JSONWriter* writer);
|
static void PrintResourceUsage(JSONWriter* writer);
|
||||||
#endif
|
|
||||||
static void PrintGCStatistics(JSONWriter* writer, Isolate* isolate);
|
static void PrintGCStatistics(JSONWriter* writer, Isolate* isolate);
|
||||||
static void PrintSystemInformation(JSONWriter* writer);
|
static void PrintSystemInformation(JSONWriter* writer);
|
||||||
static void PrintLoadedLibraries(JSONWriter* writer);
|
static void PrintLoadedLibraries(JSONWriter* writer);
|
||||||
@ -289,9 +287,7 @@ static void WriteNodeReport(Isolate* isolate,
|
|||||||
PrintGCStatistics(&writer, isolate);
|
PrintGCStatistics(&writer, isolate);
|
||||||
|
|
||||||
// Report OS and current thread resource usage
|
// Report OS and current thread resource usage
|
||||||
#ifndef _WIN32
|
|
||||||
PrintResourceUsage(&writer);
|
PrintResourceUsage(&writer);
|
||||||
#endif
|
|
||||||
|
|
||||||
writer.json_arraystart("libuv");
|
writer.json_arraystart("libuv");
|
||||||
if (env != nullptr) {
|
if (env != nullptr) {
|
||||||
@ -466,8 +462,6 @@ static void PrintGCStatistics(JSONWriter* writer, Isolate* isolate) {
|
|||||||
writer->json_objectend();
|
writer->json_objectend();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// Report resource usage (Linux/OSX only).
|
|
||||||
static void PrintResourceUsage(JSONWriter* writer) {
|
static void PrintResourceUsage(JSONWriter* writer) {
|
||||||
// Get process uptime in seconds
|
// Get process uptime in seconds
|
||||||
uint64_t uptime =
|
uint64_t uptime =
|
||||||
@ -475,30 +469,31 @@ static void PrintResourceUsage(JSONWriter* writer) {
|
|||||||
if (uptime == 0) uptime = 1; // avoid division by zero.
|
if (uptime == 0) uptime = 1; // avoid division by zero.
|
||||||
|
|
||||||
// Process and current thread usage statistics
|
// Process and current thread usage statistics
|
||||||
struct rusage stats;
|
uv_rusage_t rusage;
|
||||||
writer->json_objectstart("resourceUsage");
|
writer->json_objectstart("resourceUsage");
|
||||||
if (getrusage(RUSAGE_SELF, &stats) == 0) {
|
if (uv_getrusage(&rusage) == 0) {
|
||||||
double user_cpu =
|
double user_cpu =
|
||||||
stats.ru_utime.tv_sec + SEC_PER_MICROS * stats.ru_utime.tv_usec;
|
rusage.ru_utime.tv_sec + SEC_PER_MICROS * rusage.ru_utime.tv_usec;
|
||||||
double kernel_cpu =
|
double kernel_cpu =
|
||||||
stats.ru_stime.tv_sec + SEC_PER_MICROS * stats.ru_stime.tv_usec;
|
rusage.ru_stime.tv_sec + SEC_PER_MICROS * rusage.ru_stime.tv_usec;
|
||||||
writer->json_keyvalue("userCpuSeconds", user_cpu);
|
writer->json_keyvalue("userCpuSeconds", user_cpu);
|
||||||
writer->json_keyvalue("kernelCpuSeconds", kernel_cpu);
|
writer->json_keyvalue("kernelCpuSeconds", kernel_cpu);
|
||||||
double cpu_abs = user_cpu + kernel_cpu;
|
double cpu_abs = user_cpu + kernel_cpu;
|
||||||
double cpu_percentage = (cpu_abs / uptime) * 100.0;
|
double cpu_percentage = (cpu_abs / uptime) * 100.0;
|
||||||
writer->json_keyvalue("cpuConsumptionPercent", cpu_percentage);
|
writer->json_keyvalue("cpuConsumptionPercent", cpu_percentage);
|
||||||
writer->json_keyvalue("maxRss", stats.ru_maxrss * 1024);
|
writer->json_keyvalue("maxRss", rusage.ru_maxrss * 1024);
|
||||||
writer->json_objectstart("pageFaults");
|
writer->json_objectstart("pageFaults");
|
||||||
writer->json_keyvalue("IORequired", stats.ru_majflt);
|
writer->json_keyvalue("IORequired", rusage.ru_majflt);
|
||||||
writer->json_keyvalue("IONotRequired", stats.ru_minflt);
|
writer->json_keyvalue("IONotRequired", rusage.ru_minflt);
|
||||||
writer->json_objectend();
|
writer->json_objectend();
|
||||||
writer->json_objectstart("fsActivity");
|
writer->json_objectstart("fsActivity");
|
||||||
writer->json_keyvalue("reads", stats.ru_inblock);
|
writer->json_keyvalue("reads", rusage.ru_inblock);
|
||||||
writer->json_keyvalue("writes", stats.ru_oublock);
|
writer->json_keyvalue("writes", rusage.ru_oublock);
|
||||||
writer->json_objectend();
|
writer->json_objectend();
|
||||||
}
|
}
|
||||||
writer->json_objectend();
|
writer->json_objectend();
|
||||||
#ifdef RUSAGE_THREAD
|
#ifdef RUSAGE_THREAD
|
||||||
|
struct rusage stats;
|
||||||
if (getrusage(RUSAGE_THREAD, &stats) == 0) {
|
if (getrusage(RUSAGE_THREAD, &stats) == 0) {
|
||||||
writer->json_objectstart("uvthreadResourceUsage");
|
writer->json_objectstart("uvthreadResourceUsage");
|
||||||
double user_cpu =
|
double user_cpu =
|
||||||
@ -518,7 +513,6 @@ static void PrintResourceUsage(JSONWriter* writer) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Report operating system information.
|
// Report operating system information.
|
||||||
static void PrintSystemInformation(JSONWriter* writer) {
|
static void PrintSystemInformation(JSONWriter* writer) {
|
||||||
|
@ -43,9 +43,9 @@ function _validateContent(data) {
|
|||||||
// Verify that all sections are present as own properties of the report.
|
// Verify that all sections are present as own properties of the report.
|
||||||
const sections = ['header', 'javascriptStack', 'nativeStack',
|
const sections = ['header', 'javascriptStack', 'nativeStack',
|
||||||
'javascriptHeap', 'libuv', 'environmentVariables',
|
'javascriptHeap', 'libuv', 'environmentVariables',
|
||||||
'sharedObjects'];
|
'sharedObjects', 'resourceUsage'];
|
||||||
if (!isWindows)
|
if (!isWindows)
|
||||||
sections.push('resourceUsage', 'userLimits');
|
sections.push('userLimits');
|
||||||
|
|
||||||
if (report.uvthreadResourceUsage)
|
if (report.uvthreadResourceUsage)
|
||||||
sections.push('uvthreadResourceUsage');
|
sections.push('uvthreadResourceUsage');
|
||||||
@ -133,8 +133,7 @@ function _validateContent(data) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify the format of the resourceUsage section on non-Windows platforms.
|
// Verify the format of the resourceUsage section.
|
||||||
if (!isWindows) {
|
|
||||||
const usage = report.resourceUsage;
|
const usage = report.resourceUsage;
|
||||||
const resourceUsageFields = ['userCpuSeconds', 'kernelCpuSeconds',
|
const resourceUsageFields = ['userCpuSeconds', 'kernelCpuSeconds',
|
||||||
'cpuConsumptionPercent', 'maxRss',
|
'cpuConsumptionPercent', 'maxRss',
|
||||||
@ -152,7 +151,6 @@ function _validateContent(data) {
|
|||||||
checkForUnknownFields(usage.fsActivity, ['reads', 'writes']);
|
checkForUnknownFields(usage.fsActivity, ['reads', 'writes']);
|
||||||
assert(Number.isSafeInteger(usage.fsActivity.reads));
|
assert(Number.isSafeInteger(usage.fsActivity.reads));
|
||||||
assert(Number.isSafeInteger(usage.fsActivity.writes));
|
assert(Number.isSafeInteger(usage.fsActivity.writes));
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the format of the uvthreadResourceUsage section, if present.
|
// Verify the format of the uvthreadResourceUsage section, if present.
|
||||||
if (report.uvthreadResourceUsage) {
|
if (report.uvthreadResourceUsage) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user