feat: Add startup log utility with system info and ASCII banner
This commit is contained in:
177
server/utils/startupLog.js
Normal file
177
server/utils/startupLog.js
Normal file
@@ -0,0 +1,177 @@
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
/**
|
||||
* Startup Log Utility
|
||||
* Displays comprehensive system information and branding on server start
|
||||
*/
|
||||
|
||||
function getSystemInfo() {
|
||||
return {
|
||||
hostname: os.hostname(),
|
||||
platform: os.platform(),
|
||||
arch: os.arch(),
|
||||
nodeVersion: process.version,
|
||||
cpuCores: os.cpus().length,
|
||||
totalMemory: (os.totalmem() / 1024 / 1024 / 1024).toFixed(2) + ' GB',
|
||||
freeMemory: (os.freemem() / 1024 / 1024 / 1024).toFixed(2) + ' GB',
|
||||
uptime: process.uptime().toFixed(2) + 's'
|
||||
};
|
||||
}
|
||||
|
||||
function getProcessInfo() {
|
||||
const memUsage = process.memoryUsage();
|
||||
return {
|
||||
pid: process.pid,
|
||||
heapUsed: (memUsage.heapUsed / 1024 / 1024).toFixed(2) + ' MB',
|
||||
heapTotal: (memUsage.heapTotal / 1024 / 1024).toFixed(2) + ' MB',
|
||||
external: (memUsage.external / 1024 / 1024).toFixed(2) + ' MB'
|
||||
};
|
||||
}
|
||||
|
||||
function checkDirectories(dirs) {
|
||||
const status = {};
|
||||
dirs.forEach(({ name, path: dirPath }) => {
|
||||
status[name] = {
|
||||
exists: fs.existsSync(dirPath),
|
||||
path: dirPath,
|
||||
writable: false
|
||||
};
|
||||
|
||||
// Check write permissions if directory exists
|
||||
if (status[name].exists) {
|
||||
try {
|
||||
fs.accessSync(dirPath, fs.constants.W_OK);
|
||||
status[name].writable = true;
|
||||
} catch (err) {
|
||||
status[name].writable = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
return status;
|
||||
}
|
||||
|
||||
function getAppVersion() {
|
||||
try {
|
||||
const packagePath = path.join(__dirname, '../../package.json');
|
||||
if (fs.existsSync(packagePath)) {
|
||||
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
||||
return pkg.version || 'unknown';
|
||||
}
|
||||
} catch (err) {
|
||||
// Silently fail
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
function logStartupBanner(config = {}) {
|
||||
const {
|
||||
appName = 'BREEDR',
|
||||
port = 3000,
|
||||
environment = 'development',
|
||||
dataDir = './data',
|
||||
uploadPath = './uploads',
|
||||
staticPath = './static',
|
||||
dbStatus = 'unknown'
|
||||
} = config;
|
||||
|
||||
const version = getAppVersion();
|
||||
const sysInfo = getSystemInfo();
|
||||
const procInfo = getProcessInfo();
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
const directories = [
|
||||
{ name: 'Data', path: dataDir },
|
||||
{ name: 'Uploads', path: uploadPath },
|
||||
{ name: 'Static', path: staticPath }
|
||||
];
|
||||
const dirStatus = checkDirectories(directories);
|
||||
|
||||
// ASCII Banner
|
||||
console.log('\n');
|
||||
console.log('╔══════════════════════════════════════════════════════════╗');
|
||||
console.log('║ ║');
|
||||
console.log('║ ██████╗ ██████╗ ███████╗███████╗██████╗ ██████╗ ║');
|
||||
console.log('║ ██╔══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗██╔══██╗ ║');
|
||||
console.log('║ ██████╔╝██████╔╝█████╗ █████╗ ██║ ██║██████╔╝ ║');
|
||||
console.log('║ ██╔══██╗██╔══██╗██╔══╝ ██╔══╝ ██║ ██║██╔══██╗ ║');
|
||||
console.log('║ ██████╔╝██║ ██║███████╗███████╗██████╔╝██║ ██║ ║');
|
||||
console.log('║ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝ ║');
|
||||
console.log('║ ║');
|
||||
console.log('║ Dog Breeding Genealogy Management System ║');
|
||||
console.log('║ ║');
|
||||
console.log('╚══════════════════════════════════════════════════════════╝');
|
||||
console.log('');
|
||||
|
||||
// Application Info
|
||||
console.log('┌─────────────────────────────────────────────────────────┐');
|
||||
console.log('│ 📦 APPLICATION INFO │');
|
||||
console.log('├─────────────────────────────────────────────────────────┤');
|
||||
console.log(`│ Version : ${version.padEnd(40)} │`);
|
||||
console.log(`│ Environment : ${environment.padEnd(40)} │`);
|
||||
console.log(`│ Started : ${timestamp.padEnd(40)} │`);
|
||||
console.log(`│ Node.js : ${sysInfo.nodeVersion.padEnd(40)} │`);
|
||||
console.log('└─────────────────────────────────────────────────────────┘');
|
||||
console.log('');
|
||||
|
||||
// Server Configuration
|
||||
console.log('┌─────────────────────────────────────────────────────────┐');
|
||||
console.log('│ 🌐 SERVER CONFIGURATION │');
|
||||
console.log('├─────────────────────────────────────────────────────────┤');
|
||||
console.log(`│ Port : ${String(port).padEnd(40)} │`);
|
||||
console.log(`│ Access URL : http://localhost:${port}${' '.repeat(27)} │`);
|
||||
console.log(`│ Database : ${dbStatus.padEnd(40)} │`);
|
||||
console.log('└─────────────────────────────────────────────────────────┘');
|
||||
console.log('');
|
||||
|
||||
// Directory Status
|
||||
console.log('┌─────────────────────────────────────────────────────────┐');
|
||||
console.log('│ 📁 DIRECTORY STATUS │');
|
||||
console.log('├─────────────────────────────────────────────────────────┤');
|
||||
Object.entries(dirStatus).forEach(([name, status]) => {
|
||||
const statusIcon = status.exists ? (status.writable ? '✓' : '⚠') : '✗';
|
||||
const statusText = status.exists ? (status.writable ? 'OK' : 'READ-ONLY') : 'MISSING';
|
||||
console.log(`│ ${statusIcon} ${name.padEnd(10)} : ${statusText.padEnd(10)} ${status.path.substring(0, 25).padEnd(25)} │`);
|
||||
});
|
||||
console.log('└─────────────────────────────────────────────────────────┘');
|
||||
console.log('');
|
||||
|
||||
// System Resources
|
||||
console.log('┌─────────────────────────────────────────────────────────┐');
|
||||
console.log('│ 💻 SYSTEM RESOURCES │');
|
||||
console.log('├─────────────────────────────────────────────────────────┤');
|
||||
console.log(`│ Hostname : ${sysInfo.hostname.padEnd(40)} │`);
|
||||
console.log(`│ Platform : ${sysInfo.platform.padEnd(40)} │`);
|
||||
console.log(`│ Architecture : ${sysInfo.arch.padEnd(40)} │`);
|
||||
console.log(`│ CPU Cores : ${String(sysInfo.cpuCores).padEnd(40)} │`);
|
||||
console.log(`│ Total Memory : ${sysInfo.totalMemory.padEnd(40)} │`);
|
||||
console.log(`│ Free Memory : ${sysInfo.freeMemory.padEnd(40)} │`);
|
||||
console.log('└─────────────────────────────────────────────────────────┘');
|
||||
console.log('');
|
||||
|
||||
// Process Info
|
||||
console.log('┌─────────────────────────────────────────────────────────┐');
|
||||
console.log('│ ⚙️ PROCESS INFO │');
|
||||
console.log('├─────────────────────────────────────────────────────────┤');
|
||||
console.log(`│ PID : ${String(procInfo.pid).padEnd(40)} │`);
|
||||
console.log(`│ Heap Used : ${procInfo.heapUsed.padEnd(40)} │`);
|
||||
console.log(`│ Heap Total : ${procInfo.heapTotal.padEnd(40)} │`);
|
||||
console.log(`│ External : ${procInfo.external.padEnd(40)} │`);
|
||||
console.log(`│ Uptime : ${sysInfo.uptime.padEnd(40)} │`);
|
||||
console.log('└─────────────────────────────────────────────────────────┘');
|
||||
console.log('');
|
||||
|
||||
// Ready message
|
||||
console.log('🚀 Server is ready and listening for connections');
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
logStartupBanner,
|
||||
getSystemInfo,
|
||||
getProcessInfo,
|
||||
checkDirectories,
|
||||
getAppVersion
|
||||
};
|
||||
Reference in New Issue
Block a user