Skip to content

Commit 0cdc46f

Browse files
committed
process: add custom directory in heapsnapshot
1 parent 9e5e2f1 commit 0cdc46f

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

lib/internal/process/pre_execution.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ const {
88
ObjectGetOwnPropertyDescriptor,
99
SafeMap,
1010
StringPrototypeStartsWith,
11+
Date,
12+
DatePrototypeToLocaleDateString,
13+
DatePrototypeToTimeString,
1114
globalThis,
1215
} = primordials;
1316

@@ -365,6 +368,7 @@ function initializeReportSignalHandlers() {
365368

366369
function initializeHeapSnapshotSignalHandlers() {
367370
const signal = getOptionValue('--heapsnapshot-signal');
371+
const diagnosticDir = getOptionValue('--diagnostic-dir');
368372

369373
if (!signal)
370374
return;
@@ -373,7 +377,8 @@ function initializeHeapSnapshotSignalHandlers() {
373377
const { writeHeapSnapshot } = require('v8');
374378

375379
function doWriteHeapSnapshot() {
376-
writeHeapSnapshot();
380+
const heapSnapshotFilename = getHeapSnapshotFilename(diagnosticDir);
381+
writeHeapSnapshot(heapSnapshotFilename);
377382
}
378383
process.on(signal, doWriteHeapSnapshot);
379384

@@ -650,6 +655,22 @@ function markBootstrapComplete() {
650655
internalBinding('performance').markBootstrapComplete();
651656
}
652657

658+
// Sequence number for diagnostic filenames
659+
let sequenceNumOfheapSnapshot = 0;
660+
661+
function getHeapSnapshotFilename(diagnosticDir) {
662+
if (!diagnosticDir) return undefined;
663+
664+
const date = new Date();
665+
const formattedDateString = DatePrototypeToLocaleDateString(date).split('/').reverse().join('');
666+
const formattedTimeString = DatePrototypeToTimeString(date).split(' ')[0].replaceAll(':', '');
667+
const pid = process.pid;
668+
const threadId = internalBinding('worker').threadId;
669+
const fileSequence = (++sequenceNumOfheapSnapshot).toString().padStart(3, '0');
670+
671+
return `${diagnosticDir}/Heap.${formattedDateString}.${formattedTimeString}.${pid}.${threadId}.${fileSequence}.heapsnapshot`;
672+
}
673+
653674
module.exports = {
654675
setupUserModules,
655676
prepareMainThreadExecution,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
if (common.isWindows)
5+
common.skip('test not supported on Windows');
6+
7+
const assert = require('assert');
8+
9+
if (process.argv[2] === 'child') {
10+
const fs = require('fs');
11+
12+
assert.strictEqual(process.listenerCount('SIGUSR2'), 1);
13+
process.kill(process.pid, 'SIGUSR2');
14+
process.kill(process.pid, 'SIGUSR2');
15+
16+
// Asynchronously wait for the snapshot. Use an async loop to be a bit more
17+
// robust in case platform or machine differences throw off the timing.
18+
(function validate() {
19+
const files = fs.readdirSync(process.cwd());
20+
21+
if (files.length === 0)
22+
return setImmediate(validate);
23+
24+
assert.strictEqual(files.length, 2);
25+
26+
for (let i = 0; i < files.length; i++) {
27+
assert.match(files[i], /^Heap\..+\.heapsnapshot$/);
28+
JSON.parse(fs.readFileSync(files[i]));
29+
}
30+
})();
31+
} else {
32+
const { spawnSync } = require('child_process');
33+
const tmpdir = require('../common/tmpdir');
34+
35+
tmpdir.refresh();
36+
const args = ['--heapsnapshot-signal', 'SIGUSR2', '--diagnostic-dir', tmpdir.path, __filename, 'child'];
37+
const child = spawnSync(process.execPath, args, { cwd: tmpdir.path });
38+
39+
assert.strictEqual(child.status, 0);
40+
assert.strictEqual(child.signal, null);
41+
}

0 commit comments

Comments
 (0)