Native Node module to capture stack traces from all registered threads.
This allows capturing main and worker thread stack traces from another watchdog thread, even if the event loops are blocked.
In the main or worker threads:
const { registerThread } = require("@sentry-internal/node-native-stacktrace");
registerThread();
Watchdog thread:
const { captureStackTrace } = require("@sentry-internal/node-native-stacktrace");
const stacks = captureStackTrace();
console.log(stacks);
Results in:
{
'0': [
{
function: 'from',
filename: 'node:buffer',
lineno: 298,
colno: 28
},
{
function: 'pbkdf2Sync',
filename: 'node:internal/crypto/pbkdf2',
lineno: 78,
colno: 17
},
{
function: 'longWork',
filename: '/app/test.js',
lineno: 20,
colno: 29
},
{
function: '?',
filename: '/app/test.js',
lineno: 24,
colno: 1
}
],
'2': [
{
function: 'from',
filename: 'node:buffer',
lineno: 298,
colno: 28
},
{
function: 'pbkdf2Sync',
filename: 'node:internal/crypto/pbkdf2',
lineno: 78,
colno: 17
},
{
function: 'longWork',
filename: '/app/worker.js',
lineno: 10,
colno: 29
},
{
function: '?',
filename: '/app/worker.js',
lineno: 14,
colno: 1
}
]
}
In the main or worker threads if you call registerThread()
regularly, times
are recorded.
const { registerThread } = require("@sentry-internal/node-native-stacktrace");
setInterval(() => {
registerThread();
}, 200);
In the watchdog thread you can call getThreadsLastSeen()
to get how long it's
been in milliseconds since each thread registered.
If any thread has exceeded a threshold, you can call captureStackTrace()
to
get the stack traces for all threads.
const {
captureStackTrace,
getThreadsLastSeen,
} = require("@sentry-internal/node-native-stacktrace");
const THRESHOLD = 1000; // 1 second
setInterval(() => {
for (const [thread, time] in Object.entries(getThreadsLastSeen())) {
if (time > THRESHOLD) {
const stacks = captureStackTrace();
const blockedThread = stacks[thread];
console.log(
`Thread '${thread}' blocked more than ${THRESHOLD}ms`,
blockedThread,
);
}
}
}, 1000);