Skip to content
This repository has been archived by the owner on Jun 18, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2 from rnchamberlain/initial-drop
Browse files Browse the repository at this point in the history
Initial drop of nodereport project for nodejs repo
  • Loading branch information
rnchamberlain authored Oct 21, 2016
2 parents 72bc4d6 + 7cd3f76 commit 1ba381f
Show file tree
Hide file tree
Showing 16 changed files with 1,773 additions and 2 deletions.
38 changes: 38 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app
*.node

# Project files
*.project
*.cproject

# Build directories
/build/
/node_modules/
59 changes: 57 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,65 @@
# nodereport

nodereport is an add-on for Node.js, delivered as an NPM module,
nodereport is an add-on for Node.js, delivered as an NPM native module,
which provides a human-readable diagnostic summary report, written
to file. The report is intended for development, test and production
use, to capture and preserve information for problem determination.
It includes Javascript and native stack traces, heap statistics,
platform information and resource usage etc. With the report enabled,
reports are triggered on unhandled exceptions, fatal errors, signals
reports can be triggered on unhandled exceptions, fatal errors, signals
and calls to a Javascript API.

Usage:

npm install nodejs/nodereport

var nodereport = require('nodereport');

By default, this will allow a NodeReport to be triggered via an API
call from a JavaScript application. The filename of the NodeReport is
returned. The default filename includes the date, time, PID and a
sequence number. Alternatively a filename can be specified on the API call.

nodereport.triggerReport();

var filename = nodereport.triggerReport();

nodereport.triggerReport("myReportName");

Content of the NodeReport in the initial implementation consists of a
header section containing the event type, date, time, PID and Node version,
sections containing Javascript and native stack traces, a section containing
V8 heap information, a section containing libuv handle information and an OS
platform information section showing CPU and memory usage and system limits.
The following messages are issued to stderr when a NodeReport is triggered:

Writing Node.js error report to file: NodeReport.201605113.145311.26249.001.txt
Node.js error report completed

A NodeReport can also be triggered on unhandled exception and fatal error
events, and/or signals (Linux/OSX only). These and other options can be
enabled or disabled using the following APIs:

nodereport.setEvents("exception+fatalerror+signal+apicall");
nodereport.setSignal("SIGUSR2|SIGQUIT");
nodereport.setFileName("stdout|stderr|<filename>");
nodereport.setDirectory("<full path>");
nodereport.setCoreDump("yes|no");
nodereport.setVerbose("yes|no");

Configuration on module initialisation is also available via environment variables:

export NODEREPORT_EVENTS=exception+fatalerror+signal+apicall
export NODEREPORT_SIGNAL=SIGUSR2|SIGQUIT
export NODEREPORT_FILENAME=stdout|stderr|<filename>
export NODEREPORT_DIRECTORY=<full path>
export NODEREPORT_COREDUMP=yes|no
export NODEREPORT_VERBOSE=yes|no

Sample programs for triggering NodeReports are provided in the
node_modules/nodereport/demo directory:

api.js - NodeReport triggered by Javascript API call
exception.js - NodeReport triggered by unhandled exception
fatalerror.js - NodeReport triggered by fatal error on Javascript heap out of memory
loop.js - looping application, NodeReport triggered using kill -USR2 <pid>
30 changes: 30 additions & 0 deletions binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"targets": [
{
"target_name": "nodereport",
"sources": [ "src/node_report.cc", "src/module.cc" ],
"include_dirs": [ '<!(node -e "require(\'nan\')")' ],
"conditions": [
["OS=='linux'", {
"defines": [ "_GNU_SOURCE" ],
"cflags": [ "-g", "-O2", "-std=c++11", ],
}],
["OS=='win'", {
"libraries": [ "dbghelp.lib" ],
"dll_files": [ "dbghelp.dll" ],
}],
],
},
{
"target_name": "install",
"type":"none",
"dependencies" : [ "nodereport" ],
"copies": [
{
"destination": "<(module_root_dir)",
"files": ["<(module_root_dir)/build/Release/nodereport.node"]
}]
},
],
}

35 changes: 35 additions & 0 deletions demo/api_call.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Example - generation of NodeReport via API call
var nodereport = require('nodereport');
var http = require("http");

var count = 0;

function my_listener(request, response) {
switch(count++) {
case 0:
response.writeHead(200,{"Content-Type": "text/plain"});
response.write("\nRunning NodeReport API demo... refresh page to trigger NodeReport");
response.end();
break;
case 1:
response.writeHead(200,{"Content-Type": "text/plain"});
// Call the nodereport module to trigger a NodeReport
var filename = nodereport.triggerReport();
response.write("\n" + filename + " written - refresh page to close");
response.end();
break;
default:
process.exit(0);
}
}

var http_server = http.createServer(my_listener);
http_server.listen(8080);

console.log('api_call.js: Node running');
console.log('api_call.js: Go to http://<machine>:8080/ or http://localhost:8080/');

setTimeout(function(){
console.log('api_call.js: test timeout expired, exiting.');
process.exit(0);
}, 60000);
33 changes: 33 additions & 0 deletions demo/exception.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Example - generation of NodeReport on uncaught exception
require('nodereport').setEvents("exception");
var http = require("http");

var count = 0;

function my_listener(request, response) {
switch(count++) {
case 0:
response.writeHead(200,{"Content-Type": "text/plain"});
response.write("\nRunning NodeReport exception demo... refresh page to cause exception (application will terminate)");
response.end();
break;
default:
throw new UserException('*** exception.js: exception thrown from my_listener()');
}
}

function UserException(message) {
this.message = message;
this.name = "UserException";
}

var http_server = http.createServer(my_listener);
http_server.listen(8080);

console.log('exception.js: Node running');
console.log('exception.js: Go to http://<machine>:8080/ or http://localhost:8080/');

setTimeout(function() {
console.log('exception.js: test timeout expired, exiting.');
process.exit(0);
}, 60000);
41 changes: 41 additions & 0 deletions demo/fatalerror.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Example - generation of Nodereport on fatal error (Javascript heap OOM)
require('nodereport').setEvents("fatalerror");
var http = require('http');

var count = 0;

function my_listener(request, response) {
switch(count++) {
case 0:
response.writeHead(200,{"Content-Type": "text/plain"});
response.write("\nRunning NodeReport fatal error demo... refresh page to trigger excessive memory usage (application will terminate)");
response.end();
break;
case 1:
console.log('heap_oom.js: allocating excessive Javascript heap memory....');
var list = [];
while (true) {
list.push(new MyRecord());
}
response.end();
break;
}
}

function MyRecord() {
this.name = 'foo';
this.id = 128;
this.account = 98454324;
}

var http_server = http.createServer(my_listener);
http_server.listen(8080);

console.log('fatalerror.js: Node running');
console.log('fatalerror.js: Note: heap default is 1.4Gb, use --max-old-space-size=<size in Mb> to change');
console.log('fatalerror.js: Go to http://<machine>:8080/ or http://localhost:8080/');

setTimeout(function(){
console.log('fatalerror.js: timeout expired, exiting.');
process.exit(0);
}, 60000);
53 changes: 53 additions & 0 deletions demo/loop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Example - geneation of Nodereport via signal for a looping application
require('nodereport').setEvents("signal");
var http = require("http");

var count = 0;

function my_listener(request, response) {
switch(count++) {
case 0:
response.writeHead(200,{"Content-Type": "text/plain"});
response.write("\nRunning NodeReport looping application demo. Node process ID = " + process.pid);
response.write("\n\nRefresh page to enter loop, then use 'kill -USR2 " + process.pid + "' to trigger NodeReport");
response.end();
break;
case 1:
console.log("loop.js: going to loop now, use 'kill -USR2 " + process.pid + "' to trigger NodeReport");
var list = [];
for (var i=0; i<10000000000; i++) {
for (var j=0; i<1000; i++) {
list.push(new MyRecord());
}
for (var j=0; i<1000; i++) {
list[j].id += 1;
list[j].account += 2;
}
for (var j=0; i<1000; i++) {
list.pop();
}
}
response.writeHead(200,{"Content-Type": "text/plain"});
response.write("\nNodeReport demo.... finished looping");
response.end();
break;
default:
}
}

function MyRecord() {
this.name = 'foo';
this.id = 128;
this.account = 98454324;
}

var http_server = http.createServer(my_listener);
http_server.listen(8080);

console.log('loop.js: Node running');
console.log('loop.js: Go to http://<machine>:8080/ or http://localhost:8080/');

setTimeout(function() {
console.log('loop.js: timeout expired, exiting.');
process.exit(0);
}, 60000);
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "nodereport",
"main": "build/Release/nodereport.node",
"version": "0.1.0",
"description": "Diagnostic NodeReport",
"homepage": "https://github.com/nodejs/nodereport",
"repository": {
"type": "git",
"url": "https://github.com/nodejs/nodereport.git"
},
"engines": {
"node": ">=4.0.0"
},
"dependencies": {
"nan": "^2.3.5"
},
"license": "MIT",
"scripts": {
"test": "node test/autorun.js"
}
}
Loading

0 comments on commit 1ba381f

Please sign in to comment.