From 86a7cb27ec4f4058c81ace4526c5c92e9252ff2e Mon Sep 17 00:00:00 2001 From: Richard Chamberlain Date: Wed, 23 Nov 2016 15:51:21 +0000 Subject: [PATCH 1/3] Opt-in hooks by default This changes the default action on require('nodereport') to opt-in to the exception and fatal-error hooks, and to enable the signal handler. So 'node -r nodereport application.js' will get all the functionality without any code changes. For users programming to the API, a separate api-only entry point, require('nodereport/api') is provided. This does not enable the hooks and signal unless and until .setEvents() is called. Also includes a change to the behaviour on uncaught exception: default behaviour is now the same as the node default, ie no SIGILL/core dump --- .npmignore | 1 + binding.gyp | 6 +++--- main.js | 34 ++++++++++++++++++++++++++++++++++ package.json | 2 +- src/module.cc | 2 +- test/test-exception.js | 11 +++-------- 6 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 main.js diff --git a/.npmignore b/.npmignore index f5078ac..b7c757a 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,4 @@ * !src/** !binding.gyp +!main.js diff --git a/binding.gyp b/binding.gyp index 3d0be4e..6d4c379 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,7 +1,7 @@ { "targets": [ { - "target_name": "nodereport", + "target_name": "api", "sources": [ "src/node_report.cc", "src/module.cc" ], "include_dirs": [ ' { - const expectedExitCode = common.isWindows() ? 0xC0000005 : null; - const expectedSignal = common.isWindows() ? null : - common.isPPC() ? 'SIGTRAP' : 'SIGILL'; - tap.plan(4); - tap.equal(code, expectedExitCode, 'Process should not exit cleanly'); - tap.equal(signal, expectedSignal, - 'Process should exit with expected signal '); + child.on('exit', (code) => { + tap.plan(3); + tap.equal(code, 1, 'Process should exit with expected return code'); const reports = common.findReports(child.pid); tap.equal(reports.length, 1, 'Found reports ' + reports); const report = reports[0]; From 15a4740c1ca5db660396ca98a23af3d95cd0b24a Mon Sep 17 00:00:00 2001 From: Richard Chamberlain Date: Wed, 7 Dec 2016 13:18:09 +0000 Subject: [PATCH 2/3] Use index.js for main entry point instead of main.js Simplify exports in index.js Revert change to default behaviour on uncaught exception Update documentation Update tests to reflect default change (setEvents() not needed) --- .npmignore | 2 +- README.md | 24 ++++++++++++++---------- index.js | 20 ++++++++++++++++++++ main.js | 34 ---------------------------------- package.json | 1 - src/module.cc | 2 +- test/test-exception.js | 13 +++++++++---- test/test-fatal-error.js | 2 +- test/test-signal.js | 2 +- 9 files changed, 47 insertions(+), 53 deletions(-) create mode 100644 index.js delete mode 100644 main.js diff --git a/.npmignore b/.npmignore index b7c757a..cc94b97 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,4 @@ * !src/** !binding.gyp -!main.js +!index.js diff --git a/README.md b/README.md index 8865428..665aeb6 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,26 @@ Supports Node.js v4, v6 and v7 on Linux, MacOS, Windows and AIX. ```bash npm install nodereport +node -r nodereport app.js ``` +A NodeReport will be triggered automatically on unhandled exceptions and fatal +error events (for example out of memory errors), and can also be triggered +by sending a USR2 signal to a Node.js process (Linux/MacOS only). -This will allow a NodeReport to be triggered via an API -call from a JavaScript application. +A NodeReport can also be triggered via an API call from a JavaScript +application. ```js var nodereport = require('nodereport'); nodereport.triggerReport(); ``` +The API can be used without adding the automatic exception and fatal error +hooks and the signal handler, as follows: + +```js +var nodereport = require('nodereport/api'); +nodereport.triggerReport(); +``` Content of the NodeReport consists of a header section containing the event type, date, time, PID and Node version, sections containing JavaScript and @@ -50,19 +61,12 @@ can be specified as a parameter on the `triggerReport()` call. nodereport.triggerReport("myReportName"); ``` -A NodeReport can also be triggered automatically on unhandled exceptions, fatal -error events (for example out of memory errors), and signals (Linux/MacOS only). -Triggering on these events can be enabled using the following API call: - -```js -nodereport.setEvents("exception+fatalerror+signal+apicall"); -``` - ## Configuration Additional configuration is available using the following APIs: ```js +nodereport.setEvents("exception+fatalerror+signal+apicall"); nodereport.setSignal("SIGUSR2|SIGQUIT"); nodereport.setFileName("stdout|stderr|"); nodereport.setDirectory(""); diff --git a/index.js b/index.js new file mode 100644 index 0000000..584a97b --- /dev/null +++ b/index.js @@ -0,0 +1,20 @@ +// Main module entry point for nodereport + +var api = require('./api'); + +// Process NODEREPORT_EVENTS env var +var options = process.env.NODEREPORT_EVENTS; +if (options) { + api.setEvents(options); +} else { + // Default action - all events enabled + api.setEvents('exception+fatalerror+signal+apicall'); +} + +exports.triggerReport = api.triggerReport; +exports.setEvents = api.setEvents; +exports.setCoreDump = api.setCoreDump; +exports.setSignal = api.setSignal; +exports.setFileName = api.setFileName; +exports.setDirectory = api.setDirectory; +exports.setVerbose = api.setVerbose; diff --git a/main.js b/main.js deleted file mode 100644 index 0245b86..0000000 --- a/main.js +++ /dev/null @@ -1,34 +0,0 @@ -// Main module entry point for nodereport - -var api = require('./api'); - -// Process NODEREPORT_EVENTS env var -var options = process.env.NODEREPORT_EVENTS; -if (options) { - api.setEvents(options); -} else { - // Default action - all events enabled - api.setEvents('exception+fatalerror+signal+apicall'); -} - -exports.triggerReport = function() { - return api.triggerReport.apply(null, arguments); -}; -exports.setEvents = function() { - return api.setEvents.apply(null, arguments); -}; -exports.setCoreDump = function() { - return api.setCoreDump.apply(null, arguments); -}; -exports.setSignal = function() { - return api.setSignal.apply(null, arguments); -}; -exports.setFileName = function() { - return api.setFileName.apply(null, arguments); -}; -exports.setDirectory = function() { - return api.setDirectory.apply(null, arguments); -}; -exports.setVerbose = function() { - return api.setVerbose.apply(null, arguments); -}; \ No newline at end of file diff --git a/package.json b/package.json index 80d7f6a..436bf59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,5 @@ { "name": "nodereport", - "main": "./main", "version": "1.0.6", "description": "Diagnostic NodeReport", "homepage": "https://github.com/nodejs/nodereport#readme", diff --git a/src/module.cc b/src/module.cc index 844f777..984a86b 100644 --- a/src/module.cc +++ b/src/module.cc @@ -19,7 +19,7 @@ static void SetupSignalHandler(); // Default nodereport option settings static unsigned int nodereport_events = NR_APICALL; -static unsigned int nodereport_core = 0; +static unsigned int nodereport_core = 1; static unsigned int nodereport_verbose = 0; #ifdef _WIN32 // signal trigger not supported on Windows static unsigned int nodereport_signal = 0; diff --git a/test/test-exception.js b/test/test-exception.js index af02264..9ece583 100644 --- a/test/test-exception.js +++ b/test/test-exception.js @@ -2,7 +2,7 @@ // Testcase to produce NodeReport on uncaught exception if (process.argv[2] === 'child') { - require('../').setEvents('exception'); + require('../'); function myException(request, response) { const m = '*** exception.js: testcase exception thrown from myException()'; @@ -21,9 +21,14 @@ if (process.argv[2] === 'child') { const tap = require('tap'); const child = spawn(process.execPath, [__filename, 'child']); - child.on('exit', (code) => { - tap.plan(3); - tap.equal(code, 1, 'Process should exit with expected return code'); + child.on('exit', (code, signal) => { + const expectedExitCode = common.isWindows() ? 0xC0000005 : null; + const expectedSignal = common.isWindows() ? null : + common.isPPC() ? 'SIGTRAP' : 'SIGILL'; + tap.plan(4); + tap.equal(code, expectedExitCode, 'Process should not exit cleanly'); + tap.equal(signal, expectedSignal, + 'Process should exit with expected signal '); const reports = common.findReports(child.pid); tap.equal(reports.length, 1, 'Found reports ' + reports); const report = reports[0]; diff --git a/test/test-fatal-error.js b/test/test-fatal-error.js index 66238eb..c203066 100644 --- a/test/test-fatal-error.js +++ b/test/test-fatal-error.js @@ -2,7 +2,7 @@ // Testcase to produce NodeReport on fatal error (javascript heap OOM) if (process.argv[2] === 'child') { - require('../').setEvents('fatalerror'); + require('../'); const list = []; while (true) { diff --git a/test/test-signal.js b/test/test-signal.js index 183dbb3..e3bb090 100644 --- a/test/test-signal.js +++ b/test/test-signal.js @@ -3,7 +3,7 @@ // Testcase to produce NodeReport on signal interrupting a js busy-loop, // showing it is interruptible. if (process.argv[2] === 'child') { - require('../').setEvents('signal'); + require('../'); // Exit on loss of parent process process.on('disconnect', () => process.exit(2)); From eacc52969fd7fa6bca7b693ecd717eaaae3f3036 Mon Sep 17 00:00:00 2001 From: Richard Chamberlain Date: Wed, 7 Dec 2016 13:28:34 +0000 Subject: [PATCH 3/3] Fix var -> const nits in index.js --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 584a97b..ed52c20 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ // Main module entry point for nodereport -var api = require('./api'); +const api = require('./api'); // Process NODEREPORT_EVENTS env var -var options = process.env.NODEREPORT_EVENTS; +const options = process.env.NODEREPORT_EVENTS; if (options) { api.setEvents(options); } else {