Skip to content

Instantly share code, notes, and snippets.

@ErickWendel
Last active November 12, 2024 20:48
Show Gist options
  • Save ErickWendel/ac1483acba6b88ceb44dec319b1758cc to your computer and use it in GitHub Desktop.
Save ErickWendel/ac1483acba6b88ceb44dec319b1758cc to your computer and use it in GitHub Desktop.
Examples of how to take the cpu profilling and snapshots on applications that need to be publicly accessible
import { Session } from 'inspector/promises';
import fs from 'fs';
import net from 'net';
let session;
const now = new Date();
const profileFile = `/src/${now.getTime()}.cpuprofile`;
function createTCPServer({
onStart,
onStop,
onSnapshot
}) {
net
.createServer((socket) => {
console.log("Client connected");
socket.on("data", (data) => {
const message = data.toString().trim();
console.log("Received message:", message);
if (message === 'stop') {
onStop();
return
}
if (message === 'start') {
onStart();
return
}
if (message === 'snap') {
onSnapshot();
return
}
});
socket.on("end", () => console.log("Client disconnected"));
socket.on("error", (err) => console.error("Socket error:", err));
})
.listen(5000, () => {
console.log("Server listening on port 5000");
});
}
createTCPServer({
onStart: async () => {
_session = new Session();
_session.connect();
await _session.post('Profiler.enable')
await _session.post('Profiler.start')
console.log('started CPU profiling...');
},
onStop: async () => {
console.log('Stopping CPU profiling...');
await _session.post('NodeTracing.stop')
const { profile } = await _session.post('Profiler.stop')
// console.log(JSON.stringify(profile));
await fs.promises.writeFile(profileFile, JSON.stringify(profile));
console.log(`CPU profile saved as ${profileFile}`);
_session.disconnect();
},
onSnapshot: async () => {
// _session.on("HeapProfiler.reportHeapSnapshotProgress", (progress) => {
// console.log(`Heap snapshot progress: ${progress}`);
// });
// const filename = profileFile.replace('cpuprofile', 'heapsnapshot')
// const stream = fs.createWriteStream(filename);
// _session.on('HeapProfiler.addHeapSnapshotChunk',
// async (m) => {
// stream.write(m.params.chunk);
// })
// await _session.post('HeapProfiler.takeHeapSnapshot', null);
// await _session.post("HeapProfiler.stopTrackingHeapObjects")
// console.log(`Heap snapshot saved as ${filename}`);
},
onTracing: async () => {
const filename = profileFile.replace('cpuprofile', 'tracing')
const stream = fs.createWriteStream(filename);
_session.on('NodeTracing.dataCollected',
async (chunk) => {
stream.write(JSON.stringify(chunk.params.value));
});
_session.on('NodeTracing.tracingComplete', async () => {
stream.end();
console.log('Tracing complete');
});
const traceConfig = { includedCategories: ['v8', 'node'] };
await _session.post('NodeTracing.start', { traceConfig });
},
});
function connect() {
const client = net.connect(5000, () => {
console.log("Connected to server");
client.write("start\n"); // Send "start" once connected
});
// Pipe input/output
process.stdin.pipe(client);
client.pipe(process.stdout);
client.once("error", (err) => {
// console.error("Connection error:", err.message);
});
client.once("close", () => {
console.log("\nDisconnected from server. Reconnecting in 1 second...");
setTimeout(connect, 1000); // Reconnect after 5 seconds
});
}
connect();
// send start, stop or snap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment