Skip to content

Instantly share code, notes, and snippets.

@amirilovic
Created July 15, 2024 20:46
Show Gist options
  • Save amirilovic/fff46ddd099965a572b8216b21f613eb to your computer and use it in GitHub Desktop.
Save amirilovic/fff46ddd099965a572b8216b21f613eb to your computer and use it in GitHub Desktop.
A script that takes a heap snapshot from a nodejs process in debug mode
const { exec, spawn } = require("child_process");
const fs = require("fs");
const { promisify } = require("util");
import { WebSocket } from "ws";
async function getWebSocketDebuggerUrl() {
const res = await fetch("http://localhost:9229/json");
const data = await res.json();
return data[0].webSocketDebuggerUrl;
}
async function takeHeapSnapshot() {
let ws: WebSocket;
try {
process.on("uncaughtException", (err) => {
console.error(err);
process.exit(1);
});
// Create temp file
const fileName = "profile-" + Date.now() + ".heapsnapshot";
console.log("File: ", fileName);
// Get the WebSocket URL
const webSocketDebuggerUrl = await getWebSocketDebuggerUrl();
console.log("WebSocket URL:", webSocketDebuggerUrl);
await new Promise<void>((resolve) => {
// use WebSocket to connect to the target process
ws = new WebSocket(webSocketDebuggerUrl);
let startedReceiving = false;
// listen for addChunk events
ws.on("message", (data) => {
const message = JSON.parse(data.toString());
if (message.method === "HeapProfiler.addHeapSnapshotChunk") {
if (!startedReceiving) {
startedReceiving = true;
console.log("Receiving HeapSnapshot...");
}
fs.appendFileSync(fileName, message.params.chunk);
} else if (message.id === 2) {
resolve();
}
});
ws.on("error", console.error);
ws.on("open", function open() {
console.log("connected");
// Enable the HeapProfiler
console.log("Enabling HeapProfiler...");
ws.send(
JSON.stringify({
id: 1,
method: "HeapProfiler.enable",
})
);
// Take the HeapSnapshot
console.log("Taking HeapSnapshot...");
ws.send(
JSON.stringify({
id: 2,
method: "HeapProfiler.takeHeapSnapshot",
})
);
});
});
console.log("Heap Snapshot captured!");
} catch (err) {
console.error("An error occurred:", err);
} finally {
if (ws) {
ws.close();
}
}
}
takeHeapSnapshot();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment