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
JavaScript
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);