UNPKG

bodhi-node-profiler

Version:

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

137 lines (116 loc) 3.6 kB
#!/usr/bin/env node const { program } = require('commander'); const { BodhiProfiler } = require('../dist/index'); const chalk = require('chalk'); const ora = require('ora'); const clear = require('clear'); const figlet = require('figlet'); const Table = require('cli-table3'); // Initialize CLI clear(); console.log( chalk.cyan( figlet.textSync('Bodhi Profiler', { horizontalLayout: 'full' }) ) ); program .version(require('../package.json').version) .description(chalk.cyan('Bodhi Node Profiler - Performance Monitoring Tool')); program .command('monitor') .description('Start monitoring in terminal') .option('-p, --port <number>', 'Dashboard port', '45678') .option('-i, --interval <number>', 'Refresh interval in ms', '1000') .option('-l, --log-path <string>', 'Log file path', './logs') .action((options) => { const spinner = ora('Starting monitoring...').start(); const profiler = new BodhiProfiler({ port: parseInt(options.port), logPath: options.logPath, enableWebDashboard: true }); const updateMetrics = () => { const metrics = profiler.getStats(); displayMetrics(metrics, options.port); }; setInterval(updateMetrics, parseInt(options.interval)); updateMetrics(); // Initial update }); program .command('dashboard') .description('Start web dashboard') .option('-p, --port <number>', 'Dashboard port', '45678') .action((options) => { const profiler = new BodhiProfiler({ port: parseInt(options.port), enableWebDashboard: true }); console.log(chalk.green('\n✓ Dashboard started successfully!')); console.log(chalk.cyan(`\nAccess your dashboard at: http://localhost:${options.port}/profiler/stats`)); }); function displayMetrics(metrics, port) { clear(); // Header console.log(chalk.cyan( figlet.textSync('Bodhi Profiler', { horizontalLayout: 'full' }) )); // System Metrics Table const systemTable = new Table({ head: [ chalk.cyan('Metric'), chalk.cyan('Value'), chalk.cyan('Status') ] }); const cpuUsage = metrics.cpu.percentage; const memoryUsage = (metrics.memory.heapUsed / metrics.memory.heapTotal) * 100; systemTable.push( [ 'CPU Usage', `${cpuUsage.toFixed(2)}%`, getStatusIndicator(cpuUsage, 80) ], [ 'Memory Usage', `${memoryUsage.toFixed(2)}%`, getStatusIndicator(memoryUsage, 85) ], [ 'Event Loop Delay', `${metrics.eventLoopDelay.toFixed(2)}ms`, getStatusIndicator(metrics.eventLoopDelay, 100) ] ); console.log(systemTable.toString()); // API Metrics if (metrics.apiResponses && metrics.apiResponses.size > 0) { const apiTable = new Table({ head: [ chalk.cyan('Endpoint'), chalk.cyan('Response Time'), chalk.cyan('Status') ] }); metrics.apiResponses.forEach((duration, route) => { apiTable.push([ route, `${duration.toFixed(2)}ms`, getStatusIndicator(duration, 1000) ]); }); console.log('\nAPI Performance:'); console.log(apiTable.toString()); } // Update timestamp console.log(chalk.gray(`\nLast Updated: ${new Date().toLocaleTimeString()}`)); console.log(chalk.cyan(`\nDashboard: http://localhost:${port}/profiler/stats`)); } function getStatusIndicator(value, threshold) { if (value > threshold) { return chalk.red('⚠️ High'); } else if (value > threshold * 0.8) { return chalk.yellow('⚠️ Warning'); } return chalk.green('✓ Good'); } program.parse(process.argv);