UNPKG

bodhi-node-profiler

Version:

A lightweight, zero-configuration performance profiler for Node.js applications with real-time dashboard

103 lines (93 loc) 3.36 kB
let charts = { cpu: null, memory: null, eventLoop: null }; const createChart = (ctx, label) => { return new Chart(ctx, { type: 'line', data: { labels: [], datasets: [{ label: label, data: [], borderColor: 'rgb(75, 192, 192)', tension: 0.1 }] }, options: { responsive: true, animation: false, scales: { y: { beginAtZero: true } } } }); }; const initializeCharts = () => { charts.cpu = createChart(document.getElementById('cpuChart').getContext('2d'), 'CPU %'); charts.memory = createChart(document.getElementById('memoryChart').getContext('2d'), 'Memory Usage (MB)'); charts.eventLoop = createChart(document.getElementById('eventLoopChart').getContext('2d'), 'Delay (ms)'); }; const updateCharts = (metrics) => { const timestamp = new Date().toLocaleTimeString(); // Update CPU Chart charts.cpu.data.labels.push(timestamp); charts.cpu.data.datasets[0].data.push(metrics.currentStats.cpu.usage); if (charts.cpu.data.labels.length > 20) { charts.cpu.data.labels.shift(); charts.cpu.data.datasets[0].data.shift(); } charts.cpu.update(); // Update Memory Chart const memoryUsageMB = metrics.currentStats.memory.heapUsed / 1024 / 1024; charts.memory.data.labels.push(timestamp); charts.memory.data.datasets[0].data.push(memoryUsageMB); if (charts.memory.data.labels.length > 20) { charts.memory.data.labels.shift(); charts.memory.data.datasets[0].data.shift(); } charts.memory.update(); // Update Event Loop Chart charts.eventLoop.data.labels.push(timestamp); charts.eventLoop.data.datasets[0].data.push(metrics.currentStats.eventLoopDelay); if (charts.eventLoop.data.labels.length > 20) { charts.eventLoop.data.labels.shift(); charts.eventLoop.data.datasets[0].data.shift(); } charts.eventLoop.update(); }; const updateApiTable = (metrics) => { const tableBody = document.getElementById('apiTable'); tableBody.innerHTML = ''; metrics.metrics.apiResponses.forEach((duration, route) => { const row = document.createElement('tr'); row.innerHTML = ` <td class="px-6 py-4">${route}</td> <td class="px-6 py-4">${duration.toFixed(2)}ms</td> <td class="px-6 py-4"> <span class="px-2 py-1 rounded-full text-sm ${duration > 1000 ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800'}"> ${duration > 1000 ? 'Slow' : 'Good'} </span> </td> `; tableBody.appendChild(row); }); }; const fetchMetrics = async () => { try { const response = await fetch('/api/metrics'); const metrics = await response.json(); updateCharts(metrics); updateApiTable(metrics); } catch (error) { console.error('Error fetching metrics:', error); } }; // Initialize document.addEventListener('DOMContentLoaded', () => { initializeCharts(); setInterval(fetchMetrics, 1000); });