Skip to content

Commit

Permalink
report: add --report-network-disabled option
Browse files Browse the repository at this point in the history
Adds a new option `process.report.networkDisabled` and
cli option `--report-network-disabled` which will disable
any netowkring operations for the `report` generation.

Fixes: nodejs#46060
  • Loading branch information
Ethan-Arrowood committed Feb 5, 2024
1 parent 68885d5 commit 2d5fb4e
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 9 deletions.
12 changes: 12 additions & 0 deletions doc/api/report.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
<!-- name=report -->

<!-- YAML
added: REPLACEME
-->

Delivers a JSON-formatted diagnostic summary, written to a file.

The report is intended for development, test, and production use, to capture
Expand Down Expand Up @@ -452,6 +456,9 @@ meaning of `SIGUSR2` for the said purposes.
* `--report-signal` Sets or resets the signal for report generation
(not supported on Windows). Default signal is `SIGUSR2`.

* `--report-network-disabled` Disable the `header.networkInterfaces` reporting.
Default is `false`.

A report can also be triggered via an API call from a JavaScript application:

```js
Expand Down Expand Up @@ -571,6 +578,8 @@ timestamp, PID, and sequence number.
written. URLs are not supported. Defaults to the current working directory of
the Node.js process.

`networkDisabled` disables the `header.networkInterfaces` reporting.

```js
// Trigger report only on uncaught exceptions.
process.report.reportOnFatalError = false;
Expand All @@ -587,6 +596,9 @@ process.report.reportOnFatalError = false;
process.report.reportOnUncaughtException = false;
process.report.reportOnSignal = true;
process.report.signal = 'SIGQUIT';

// Disable network interfaces reporting
process.report.networkDisabled = true;
```

Configuration on module initialization is also available via
Expand Down
7 changes: 7 additions & 0 deletions lib/internal/process/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ const report = {
validateBoolean(b, 'compact');
nr.setCompact(b);
},
get networkDisabled() {
return nr.getNetworkDisabled();
},
set networkDisabled(b) {
validateBoolean(b, 'networkDisabled');
nr.setNetworkDisabled(b);
},
get signal() {
return nr.getSignal();
},
Expand Down
6 changes: 6 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"set default TLS maximum to TLSv1.3 (default: TLSv1.3)",
&EnvironmentOptions::tls_max_v1_3,
kAllowedInEnvvar);

AddOption("--report-network-disabled",
"disable network interface diagnostics."
" (default: false)",
&EnvironmentOptions::report_network_disabled,
kAllowedInEnvvar);
}

PerIsolateOptionsParser::PerIsolateOptionsParser(
Expand Down
2 changes: 2 additions & 0 deletions src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ class EnvironmentOptions : public Options {

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

bool report_network_disabled = false;

inline DebugOptions* get_debug_options() { return &debug_options_; }
inline const DebugOptions& debug_options() const { return debug_options_; }

Expand Down
34 changes: 25 additions & 9 deletions src/node_report.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ static void WriteNodeReport(Isolate* isolate,
const std::string& filename,
std::ostream& out,
Local<Value> error,
bool compact);
static void PrintVersionInformation(JSONWriter* writer);
bool compact,
bool network_disabled = false);
static void PrintVersionInformation(JSONWriter* writer,
bool network_disabled = false);
static void PrintJavaScriptErrorStack(JSONWriter* writer,
Isolate* isolate,
Local<Value> error,
Expand Down Expand Up @@ -93,7 +95,8 @@ static void WriteNodeReport(Isolate* isolate,
const std::string& filename,
std::ostream& out,
Local<Value> error,
bool compact) {
bool compact,
bool network_disabled) {
// Obtain the current time and the pid.
TIME_TYPE tm_struct;
DiagnosticFilename::LocalTime(&tm_struct);
Expand Down Expand Up @@ -174,7 +177,7 @@ static void WriteNodeReport(Isolate* isolate,
}

// Report Node.js and OS version information
PrintVersionInformation(&writer);
PrintVersionInformation(&writer, network_disabled);
writer.json_objectend();

if (isolate != nullptr) {
Expand Down Expand Up @@ -256,7 +259,7 @@ static void WriteNodeReport(Isolate* isolate,
}

// Report Node.js version, OS version and machine information.
static void PrintVersionInformation(JSONWriter* writer) {
static void PrintVersionInformation(JSONWriter* writer, bool network_disabled) {
std::ostringstream buf;
// Report Node version
buf << "v" << NODE_VERSION_STRING;
Expand Down Expand Up @@ -300,7 +303,8 @@ static void PrintVersionInformation(JSONWriter* writer) {
}

PrintCpuInfo(writer);
PrintNetworkInterfaceInfo(writer);
if (!network_disabled)
PrintNetworkInterfaceInfo(writer);

char host[UV_MAXHOSTNAMESIZE];
size_t host_size = sizeof(host);
Expand Down Expand Up @@ -917,8 +921,18 @@ std::string TriggerNodeReport(Isolate* isolate,
compact = per_process::cli_options->report_compact;
}

bool network_disabled = env->options()->report_network_disabled;

report::WriteNodeReport(
isolate, env, message, trigger, filename, *outstream, error, compact);
isolate,
env,
message,
trigger,
filename,
*outstream,
error,
compact,
network_disabled);

// Do not close stdout/stderr, only close files we opened.
if (outfile.is_open()) {
Expand Down Expand Up @@ -969,8 +983,9 @@ void GetNodeReport(Isolate* isolate,
if (isolate != nullptr) {
env = Environment::GetCurrent(isolate);
}
bool network_disabled = env->options()->report_network_disabled;
report::WriteNodeReport(
isolate, env, message, trigger, "", out, error, false);
isolate, env, message, trigger, "", out, error, false, network_disabled);
}

// External function to trigger a report, writing to a supplied stream.
Expand All @@ -983,8 +998,9 @@ void GetNodeReport(Environment* env,
if (env != nullptr) {
isolate = env->isolate();
}
bool network_disabled = env->options()->report_network_disabled;
report::WriteNodeReport(
isolate, env, message, trigger, "", out, error, false);
isolate, env, message, trigger, "", out, error, false, network_disabled);
}

} // namespace node
17 changes: 17 additions & 0 deletions src/node_report_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ static void SetCompact(const FunctionCallbackInfo<Value>& info) {
per_process::cli_options->report_compact = compact;
}

static void GetNetworkDisabled(const FunctionCallbackInfo<Value>& info) {
Environment* env = Environment::GetCurrent(info);
info.GetReturnValue().Set(env->options()->report_network_disabled);
}

static void SetNetworkDisabled(const FunctionCallbackInfo<Value>& info) {
Mutex::ScopedLock lock(per_process::cli_options_mutex);
Environment* env = Environment::GetCurrent(info);
Isolate* isolate = env->isolate();
env->options()->report_network_disabled
= info[0]->ToBoolean(isolate)->Value();
}

static void GetDirectory(const FunctionCallbackInfo<Value>& info) {
Mutex::ScopedLock lock(per_process::cli_options_mutex);
Environment* env = Environment::GetCurrent(info);
Expand Down Expand Up @@ -174,6 +187,8 @@ static void Initialize(Local<Object> exports,
SetMethod(context, exports, "getReport", GetReport);
SetMethod(context, exports, "getCompact", GetCompact);
SetMethod(context, exports, "setCompact", SetCompact);
SetMethod(context, exports, "getNetworkDisabled", GetNetworkDisabled);
SetMethod(context, exports, "setNetworkDisabled", SetNetworkDisabled);
SetMethod(context, exports, "getDirectory", GetDirectory);
SetMethod(context, exports, "setDirectory", SetDirectory);
SetMethod(context, exports, "getFilename", GetFilename);
Expand All @@ -200,6 +215,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GetReport);
registry->Register(GetCompact);
registry->Register(SetCompact);
registry->Register(GetNetworkDisabled);
registry->Register(SetNetworkDisabled);
registry->Register(GetDirectory);
registry->Register(SetDirectory);
registry->Register(GetFilename);
Expand Down
1 change: 1 addition & 0 deletions test/cctest/test_report.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "node.h"
#include "node_report.h"

#include <string>
#include "gtest/gtest.h"
Expand Down
11 changes: 11 additions & 0 deletions test/report/test-report-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ assert.throws(() => {
}, { code: 'ERR_INVALID_ARG_TYPE' });
assert.strictEqual(process.report.compact, true);

// Verify that process.report.networkDisabled behaves properly.
assert.strictEqual(process.report.networkDisabled, false);
process.report.networkDisabled = true;
assert.strictEqual(process.report.networkDisabled, true);
process.report.networkDisabled = false;
assert.strictEqual(process.report.networkDisabled, false);
assert.throws(() => {
process.report.networkDisabled = {};
}, { code: 'ERR_INVALID_ARG_TYPE' });
assert.strictEqual(process.report.networkDisabled, false);

if (!common.isWindows) {
// Verify that process.report.signal behaves properly.
assert.strictEqual(process.report.signal, 'SIGUSR2');
Expand Down
41 changes: 41 additions & 0 deletions test/report/test-report-disable-network.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';
require('../common');
const assert = require('node:assert');
const { spawnSync } = require('node:child_process');
const tmpdir = require('../common/tmpdir');
const { describe, it, before } = require('node:test');
const fs = require('node:fs');
const helper = require('../common/report');

function validate(pid) {
const reports = helper.findReports(pid, tmpdir.path);
assert.strictEqual(reports.length, 1);
let report = fs.readFileSync(reports[0], { encoding: 'utf8' });
report = JSON.parse(report);
assert.strictEqual(report.header.networkInterfaces, undefined);
fs.unlinkSync(reports[0]);
}

describe('report network disabled option', () => {
before(() => {
tmpdir.refresh();
process.report.directory = tmpdir.path;
});

it('should be configurable with --report-network-disabled', () => {
const args = ['--report-network-disabled', '-e', 'process.report.writeReport()'];
const child = spawnSync(process.execPath, args, { cwd: tmpdir.path });
assert.strictEqual(child.status, 0);
assert.strictEqual(child.signal, null);
validate(child.pid);
});

it('should be configurable with report.networkDisabled', () => {
process.report.networkDisabled = true;
process.report.writeReport();
validate(process.pid);

const report = process.report.getReport();
assert.strictEqual(report.header.networkInterfaces, undefined);
});
});
1 change: 1 addition & 0 deletions test/report/test-report.json

Large diffs are not rendered by default.

0 comments on commit 2d5fb4e

Please sign in to comment.