Feature description
Most diagnostic features in Node.js Performance Platform help locate faults by collecting information from a specific perspective. For example, heap snapshots are used for memory issues, and profiling is used for CPU issues. These features collect data over a period to help identify problems.
A diagnostic report captures the instantaneous state of a process from a global perspective. It collects information such as stacks, system resources, and platform details to help locate faults. The JavaScriptStack is especially useful for pinpointing issues caused by long-running regular expressions and infinite loops.
Supported versions for each branch:
2.x:v2.5.23.x:v3.11.84.x:v4.3.0
Note: This feature requires that the commandx dependency of agenthub/egg-alinode is version 1.5.3 or later. Otherwise, the operation fails.
User guide
On the instance page, click Scrape Performance Data and select Diagnostic Report. On the data trends page, click Diagnostic Report. The current runtime state of the application is then output in json format to help locate faults.
The following list contains some of the most helpful output items for locating problems. Generate a diagnostic report to see the full details.
JavaScriptStack: The current JavaScript execution stack.NativeStack: The current C++ execution stack.JsHeapGcInfo: Information about each space on the heap.resource: Process resource information and event loop resource information.libuvHandleSummary: libuv handle information.system: System environment variables, resource limits, and dynamic-link libraries.FileName: The full path of the diagnostic report file.NodeJsVersion: The corresponding Node.js version.alinodeVersion: The runtime version of Node.js Performance Platform.execPath: The path of the runtime binary file.
Online analysis
On the Files page, wait for the diagnostic report to generate. Click Dump to save the application's diagnostic report file to the cloud. Then, click Analyze to perform an online analysis:
The online analysis page displays information from the diagnostic report, such as the JavaScript Stack, Native Stack, Heap Distribution, Libuv Handles, and System Details. The following application example provides more details.
Application example
Copy the demo.js code to a server or local machine and save it as demo.js. Make sure
agenthubis running, and then run the file.
$ node demo.js
http listen at 8080 pid: 26542
In a browser, open http://[your_server_address]:8080.
Click
Trigger Long Running Regular ExpressionorTrigger Infinite Loop JS functionto trigger a long-running regular expression or an infinite loop.Then, in Node.js Performance Platform, find the process by its PID. Click Diagnostic Report. Go to the
Filespage, clickDump, and then clickAnalyzeto perform an online analysis.
The most useful information, the JavaScript Stack, is shown first:

The process is blocked at the regexpCase() function invocation. At line 18, column 23, the replace operation triggered abnormal regular expression backtracking. This caused the entire process to block.
The remaining information helps pinpoint the problem, as shown in the following figures.
Native stack information

Heap distribution

Libuv handle information

System details (includes the current process environment variables, system resource limits, and shared libraries)
Additional information
The diagnostic report feature is based on
node-report.To automatically generate a diagnostic report when a
FatalErrororExceptionoccurs, set theDIAGNOSTIC_EVENTSenvironment variable tofatalerror,exception, orfatalerror+exception.
demo.js code
'use strict';
const http = require('http');
const regexpCase = function() {
let str = '<br/> ' +
' Enjoy free time after breakfast, then gather at the specified time to check out on your own.';
str += '<br/> <br/>' +
' <br/> ' +
' <br/>';
str += ' <br/>' +
' ' +
' ' +
' <br/>';
str += ' <br/> <br/>';
str += ' ' +
' ' +
' Go to the Siem Reap airport on your own according to the flight schedule to return to China.<br/>';
str += 'If airport transfer service is needed, an additional 280 will be charged per order.<br/>';
let r = String(str).replace(/(^(\s*?<br[\s\/]*?>\*?)+|(\s*?<br[\s\/]*?>\s*?)+?$)/igm, '');
};
const findSomething = function(from) {
// find something from 'from'
return [];
};
const deadLoopCase = function() {
let selected = [];
let curArr = ['item1', 'item2', 'item3'];
let arr = [];
while(selected.length < curArr.length) {
const dp = findSomething(curArr)[0];
//if (typeof dp === 'undefined') {
// break;
//}
if (selected.indexOf(dp) === -1) {
selected.push(dp);
} else {
arr = arr.filter(val => {
return val != dp
})
}
}
};
http.createServer( (req, res) => {
console.log(req.url);
switch(req.url) {
case '/regexp': {
regexpCase();
res.end('regexp case');
} break;
case '/deadloop': {
deadLoopCase();
res.end('deadloop case');
} break;
case '/exit': {
process.exit(0);
} break;
default: {
res.writeHead(200, "OK",{'Content-Type': 'text/html'});
res.write('<html><head><title>Node.js</title></head><body style="font-family:arial;">');
res.write('<h2> Regular Expression and Dead Loop Detection Example</h2>');
res.write('<p>Click on button below to trigger long time running regexp test.');
res.write('<form enctype="application/x-www-form-urlencoded" action="/regexp" method="post">');
res.write('<button>Trigger Long Running Regular Expression</button></form>');
res.write('<p>Click on button below to enter JavaScript dead loop test');
res.write('<form enctype="application/x-www-form-urlencoded" action="/deadloop" method="post">');
res.write('<button>Trigger Dead Loop JS function</button></form>');
res.write('<p>The test can be terminated only before the above cases triggered.');
res.write('<form enctype="application/x-www-form-urlencoded" action="/exit" method="post">');
res.write('<button>Exit Test</button></form>');
res.write('</form></body></html');
res.end();
} break;
}
}).listen(8080);
console.log('\nhttp listen at 8080 pid: ', process.pid);