Created
April 30, 2025 08:46
-
-
Save IdrisAkintobi/8063fc1b1acb2148dd9523a0b0792ed1 to your computer and use it in GitHub Desktop.
Javascript function to create heapsnapshot and heapprofile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const v8Profiler = require('v8-profiler-next'); | |
const fs = require('fs'); | |
const fsPromises = require('fs').promises; | |
const { join } = require('path'); | |
const appLogger = require('../logger'); | |
const wait = (timeMS) => new Promise((res) => setTimeout(res, timeMS)); | |
const snapshotsFolder = join(__dirname, '..', 'heap-snapshots'); | |
// Use synchronous methods for directory check and creation | |
if (!fs.existsSync(snapshotsFolder)) { | |
fs.mkdirSync(snapshotsFolder); | |
} | |
const THIRTY_SECONDS_IN_MILLISECONDS = 30_000; | |
/** | |
* Takes a heap snapshot with minimal impact on the main thread | |
* @returns {Promise<void>} Path to the saved snapshot file | |
*/ | |
async function createHeapSnapshot() { | |
try { | |
appLogger.info('snapshotHeap recording started...'); | |
const filename = join(snapshotsFolder, `${Date.now().toString()}.heapsnapshot`); | |
// Take the snapshot - This operation blocks the main thread. | |
const snapshot = v8Profiler.takeSnapshot(); | |
const transform = snapshot.export(); | |
const writeStream = fs.createWriteStream(filename, { flags: 'w' }); | |
transform.pipe(writeStream); | |
transform.on('finish', () => { | |
snapshot.delete(); | |
appLogger.info(`snapshot heap recording completed: ${filename}`); | |
}); | |
transform.on('error', (err) => { | |
appLogger.withError(err).error('error taking heap snapshot'); | |
}); | |
} catch (err) { | |
appLogger.withError(err).error('error in creating heap snapshot'); | |
} | |
} | |
/** | |
* Creates a heap profile over a specified duration | |
* @param {number} timeMs - Duration in milliseconds to profile | |
* @returns {Promise<void>} Path to the saved profile file | |
*/ | |
async function createHeapProfile(timeMs = THIRTY_SECONDS_IN_MILLISECONDS) { | |
try { | |
appLogger.info(`heap profiling for ${timeMs / 1000} recording started...`); | |
const filename = join(snapshotsFolder, `${Date.now().toString()}.heapprofile`); | |
// Start profiling | |
v8Profiler.startSamplingHeapProfiling(); | |
// Wait for specified duration | |
await wait(timeMs); | |
// Stop profiling and save results | |
const profile = v8Profiler.stopSamplingHeapProfiling(); | |
try { | |
await fsPromises.writeFile(filename, JSON.stringify(profile)); | |
appLogger.info(`heap profile recording completed: ${filename}`); | |
} catch (writeErr) { | |
appLogger.withError(writeErr).error('error writing heap profile to file'); | |
} | |
} catch (err) { | |
appLogger.withError(err).error('error in creating heap profile'); | |
} | |
} | |
module.exports = { | |
createHeapSnapshot, | |
createHeapProfile, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment