Skip to content

Commit 29f09f0

Browse files
Ethan-Arrowoodjoyeecheung
authored andcommitted
report: add --report-exclude-network option
New option `--report-exclude-network`, also available as `report.excludeNetwork`, enables the user to exclude networking interfaces in their diagnostic report. On some systems, this can cause the report to take minutes to generate so this option can be used to optimize that. Fixes: #46060 PR-URL: #51645 Co-authored-by: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent fc9ba17 commit 29f09f0

9 files changed

+138
-10
lines changed

doc/api/cli.md

+10
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,15 @@ Enables report to be generated when the process exits due to an uncaught
17021702
exception. Useful when inspecting the JavaScript stack in conjunction with
17031703
native stack and other runtime environment data.
17041704

1705+
### `--report-exclude-network`
1706+
1707+
<!-- YAML
1708+
added: REPLACEME
1709+
-->
1710+
1711+
Exclude `header.networkInterfaces` from the diagnostic report. By default
1712+
this is not set and the network interfaces are included.
1713+
17051714
### `-r`, `--require module`
17061715

17071716
<!-- YAML
@@ -2498,6 +2507,7 @@ Node.js options that are allowed are:
24982507
* `--redirect-warnings`
24992508
* `--report-compact`
25002509
* `--report-dir`, `--report-directory`
2510+
* `--report-exclude-network`
25012511
* `--report-filename`
25022512
* `--report-on-fatalerror`
25032513
* `--report-on-signal`

doc/api/report.md

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
99
<!-- name=report -->
1010

11+
<!-- YAML
12+
changes:
13+
- version: REPLACEME
14+
pr-url: https://github.com/nodejs/node/pull/51645
15+
description: Added `--report-exclude-network` option for excluding networking operations that can slow down report generation in some cases.
16+
-->
17+
1118
Delivers a JSON-formatted diagnostic summary, written to a file.
1219

1320
The report is intended for development, test, and production use, to capture
@@ -452,6 +459,10 @@ meaning of `SIGUSR2` for the said purposes.
452459
* `--report-signal` Sets or resets the signal for report generation
453460
(not supported on Windows). Default signal is `SIGUSR2`.
454461

462+
* `--report-exclude-network` Exclude `header.networkInterfaces` from the
463+
diagnostic report. By default this is not set and the network interfaces
464+
are included.
465+
455466
A report can also be triggered via an API call from a JavaScript application:
456467

457468
```js
@@ -571,6 +582,8 @@ timestamp, PID, and sequence number.
571582
written. URLs are not supported. Defaults to the current working directory of
572583
the Node.js process.
573584

585+
`excludeNetwork` excludes `header.networkInterfaces` from the diagnostic report.
586+
574587
```js
575588
// Trigger report only on uncaught exceptions.
576589
process.report.reportOnFatalError = false;
@@ -587,6 +600,9 @@ process.report.reportOnFatalError = false;
587600
process.report.reportOnUncaughtException = false;
588601
process.report.reportOnSignal = true;
589602
process.report.signal = 'SIGQUIT';
603+
604+
// Disable network interfaces reporting
605+
process.report.excludeNetwork = true;
590606
```
591607

592608
Configuration on module initialization is also available via

lib/internal/process/report.js

+7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ const report = {
6060
validateBoolean(b, 'compact');
6161
nr.setCompact(b);
6262
},
63+
get excludeNetwork() {
64+
return nr.getExcludeNetwork();
65+
},
66+
set excludeNetwork(b) {
67+
validateBoolean(b, 'excludeNetwork');
68+
nr.setExcludeNetwork(b);
69+
},
6370
get signal() {
6471
return nr.getSignal();
6572
},

src/node_options.cc

+6
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
780780
"set default TLS maximum to TLSv1.3 (default: TLSv1.3)",
781781
&EnvironmentOptions::tls_max_v1_3,
782782
kAllowedInEnvvar);
783+
784+
AddOption("--report-exclude-network",
785+
"exclude network interface diagnostics."
786+
" (default: false)",
787+
&EnvironmentOptions::report_exclude_network,
788+
kAllowedInEnvvar);
783789
}
784790

785791
PerIsolateOptionsParser::PerIsolateOptionsParser(

src/node_options.h

+2
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ class EnvironmentOptions : public Options {
217217

218218
std::vector<std::string> user_argv;
219219

220+
bool report_exclude_network = false;
221+
220222
inline DebugOptions* get_debug_options() { return &debug_options_; }
221223
inline const DebugOptions& debug_options() const { return debug_options_; }
222224

src/node_report.cc

+30-10
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ static void WriteNodeReport(Isolate* isolate,
6161
const std::string& filename,
6262
std::ostream& out,
6363
Local<Value> error,
64-
bool compact);
65-
static void PrintVersionInformation(JSONWriter* writer);
64+
bool compact,
65+
bool exclude_network = false);
66+
static void PrintVersionInformation(JSONWriter* writer,
67+
bool exclude_network = false);
6668
static void PrintJavaScriptErrorStack(JSONWriter* writer,
6769
Isolate* isolate,
6870
Local<Value> error,
@@ -93,7 +95,8 @@ static void WriteNodeReport(Isolate* isolate,
9395
const std::string& filename,
9496
std::ostream& out,
9597
Local<Value> error,
96-
bool compact) {
98+
bool compact,
99+
bool exclude_network) {
97100
// Obtain the current time and the pid.
98101
TIME_TYPE tm_struct;
99102
DiagnosticFilename::LocalTime(&tm_struct);
@@ -174,7 +177,7 @@ static void WriteNodeReport(Isolate* isolate,
174177
}
175178

176179
// Report Node.js and OS version information
177-
PrintVersionInformation(&writer);
180+
PrintVersionInformation(&writer, exclude_network);
178181
writer.json_objectend();
179182

180183
if (isolate != nullptr) {
@@ -256,7 +259,7 @@ static void WriteNodeReport(Isolate* isolate,
256259
}
257260

258261
// Report Node.js version, OS version and machine information.
259-
static void PrintVersionInformation(JSONWriter* writer) {
262+
static void PrintVersionInformation(JSONWriter* writer, bool exclude_network) {
260263
std::ostringstream buf;
261264
// Report Node version
262265
buf << "v" << NODE_VERSION_STRING;
@@ -300,7 +303,7 @@ static void PrintVersionInformation(JSONWriter* writer) {
300303
}
301304

302305
PrintCpuInfo(writer);
303-
PrintNetworkInterfaceInfo(writer);
306+
if (!exclude_network) PrintNetworkInterfaceInfo(writer);
304307

305308
char host[UV_MAXHOSTNAMESIZE];
306309
size_t host_size = sizeof(host);
@@ -917,8 +920,19 @@ std::string TriggerNodeReport(Isolate* isolate,
917920
compact = per_process::cli_options->report_compact;
918921
}
919922

920-
report::WriteNodeReport(
921-
isolate, env, message, trigger, filename, *outstream, error, compact);
923+
bool exclude_network = env != nullptr ? env->options()->report_exclude_network
924+
: per_process::cli_options->per_isolate
925+
->per_env->report_exclude_network;
926+
927+
report::WriteNodeReport(isolate,
928+
env,
929+
message,
930+
trigger,
931+
filename,
932+
*outstream,
933+
error,
934+
compact,
935+
exclude_network);
922936

923937
// Do not close stdout/stderr, only close files we opened.
924938
if (outfile.is_open()) {
@@ -969,8 +983,11 @@ void GetNodeReport(Isolate* isolate,
969983
if (isolate != nullptr) {
970984
env = Environment::GetCurrent(isolate);
971985
}
986+
bool exclude_network = env != nullptr ? env->options()->report_exclude_network
987+
: per_process::cli_options->per_isolate
988+
->per_env->report_exclude_network;
972989
report::WriteNodeReport(
973-
isolate, env, message, trigger, "", out, error, false);
990+
isolate, env, message, trigger, "", out, error, false, exclude_network);
974991
}
975992

976993
// External function to trigger a report, writing to a supplied stream.
@@ -983,8 +1000,11 @@ void GetNodeReport(Environment* env,
9831000
if (env != nullptr) {
9841001
isolate = env->isolate();
9851002
}
1003+
bool exclude_network = env != nullptr ? env->options()->report_exclude_network
1004+
: per_process::cli_options->per_isolate
1005+
->per_env->report_exclude_network;
9861006
report::WriteNodeReport(
987-
isolate, env, message, trigger, "", out, error, false);
1007+
isolate, env, message, trigger, "", out, error, false, exclude_network);
9881008
}
9891009

9901010
} // namespace node

src/node_report_module.cc

+15
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ static void SetCompact(const FunctionCallbackInfo<Value>& info) {
8484
per_process::cli_options->report_compact = compact;
8585
}
8686

87+
static void GetExcludeNetwork(const FunctionCallbackInfo<Value>& info) {
88+
Environment* env = Environment::GetCurrent(info);
89+
info.GetReturnValue().Set(env->options()->report_exclude_network);
90+
}
91+
92+
static void SetExcludeNetwork(const FunctionCallbackInfo<Value>& info) {
93+
Environment* env = Environment::GetCurrent(info);
94+
CHECK(info[0]->IsBoolean());
95+
env->options()->report_exclude_network = info[0]->IsTrue();
96+
}
97+
8798
static void GetDirectory(const FunctionCallbackInfo<Value>& info) {
8899
Mutex::ScopedLock lock(per_process::cli_options_mutex);
89100
Environment* env = Environment::GetCurrent(info);
@@ -174,6 +185,8 @@ static void Initialize(Local<Object> exports,
174185
SetMethod(context, exports, "getReport", GetReport);
175186
SetMethod(context, exports, "getCompact", GetCompact);
176187
SetMethod(context, exports, "setCompact", SetCompact);
188+
SetMethod(context, exports, "getExcludeNetwork", GetExcludeNetwork);
189+
SetMethod(context, exports, "setExcludeNetwork", SetExcludeNetwork);
177190
SetMethod(context, exports, "getDirectory", GetDirectory);
178191
SetMethod(context, exports, "setDirectory", SetDirectory);
179192
SetMethod(context, exports, "getFilename", GetFilename);
@@ -200,6 +213,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
200213
registry->Register(GetReport);
201214
registry->Register(GetCompact);
202215
registry->Register(SetCompact);
216+
registry->Register(GetExcludeNetwork);
217+
registry->Register(SetExcludeNetwork);
203218
registry->Register(GetDirectory);
204219
registry->Register(SetDirectory);
205220
registry->Register(GetFilename);

test/report/test-report-config.js

+11
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ assert.throws(() => {
6666
}, { code: 'ERR_INVALID_ARG_TYPE' });
6767
assert.strictEqual(process.report.compact, true);
6868

69+
// Verify that process.report.excludeNetwork behaves properly.
70+
assert.strictEqual(process.report.excludeNetwork, false);
71+
process.report.excludeNetwork = true;
72+
assert.strictEqual(process.report.excludeNetwork, true);
73+
process.report.excludeNetwork = false;
74+
assert.strictEqual(process.report.excludeNetwork, false);
75+
assert.throws(() => {
76+
process.report.excludeNetwork = {};
77+
}, { code: 'ERR_INVALID_ARG_TYPE' });
78+
assert.strictEqual(process.report.excludeNetwork, false);
79+
6980
if (!common.isWindows) {
7081
// Verify that process.report.signal behaves properly.
7182
assert.strictEqual(process.report.signal, 'SIGUSR2');
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('node:assert');
4+
const { spawnSync } = require('node:child_process');
5+
const tmpdir = require('../common/tmpdir');
6+
const { describe, it, before } = require('node:test');
7+
const fs = require('node:fs');
8+
const helper = require('../common/report');
9+
10+
function validate(pid) {
11+
const reports = helper.findReports(pid, tmpdir.path);
12+
assert.strictEqual(reports.length, 1);
13+
let report = fs.readFileSync(reports[0], { encoding: 'utf8' });
14+
report = JSON.parse(report);
15+
assert.strictEqual(report.header.networkInterfaces, undefined);
16+
fs.unlinkSync(reports[0]);
17+
}
18+
19+
describe('report exclude network option', () => {
20+
before(() => {
21+
tmpdir.refresh();
22+
process.report.directory = tmpdir.path;
23+
});
24+
25+
it('should be configurable with --report-exclude-network', () => {
26+
const args = ['--report-exclude-network', '-e', 'process.report.writeReport()'];
27+
const child = spawnSync(process.execPath, args, { cwd: tmpdir.path });
28+
assert.strictEqual(child.status, 0);
29+
assert.strictEqual(child.signal, null);
30+
validate(child.pid);
31+
});
32+
33+
it('should be configurable with report.excludeNetwork', () => {
34+
process.report.excludeNetwork = true;
35+
process.report.writeReport();
36+
validate(process.pid);
37+
38+
const report = process.report.getReport();
39+
assert.strictEqual(report.header.networkInterfaces, undefined);
40+
});
41+
});

0 commit comments

Comments
 (0)