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 };