UNPKG

logit-pro

Version:

A flexible logging package that supports level-based logging (debug, info, warn, error) and automatic log rotation (daily, weekly, monthly, yearly). Easily configure log levels and rotation to suit your needs.

128 lines (105 loc) 4.9 kB
// index.js const fs = require('fs'); const path = require('path'); // Default configuration (can be overridden by user) const defaultConfig = { logDirectory: './logs', // Log file directory logLevel: 'debug', // Default log level (can be 'debug', 'info', 'warn', 'error') fileName: 'logit-pro.log', // Default log file name, can be overridden by the user rotateBy: 'daily', // Rotation type ('daily', 'weekly', 'monthly', 'yearly') }; // Levels of logging const levels = ['debug', 'info', 'warn', 'error']; // Function to format date to human-readable format for log entries (YYYY-MM-DD HH:mm:ss) function formatDateForLog(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } // Function to format date for file name (YYYY-MM-DD, YYYY-MM, etc.) function formatDateForFile(date, rotationType) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); let period = ''; if (rotationType === 'daily') { period = `${year}-${month}-${day}`; // e.g., 2025-07-17 } else if (rotationType === 'monthly') { period = `${year}-${month}`; // e.g., 2025-07 } else if (rotationType === 'yearly') { period = `${year}`; // e.g., 2025 } else if (rotationType === 'weekly') { // Get the first day of the week (Sunday) const firstDayOfWeek = new Date(date); firstDayOfWeek.setDate(date.getDate() - date.getDay()); // Adjust to the first day of the week (Sunday) const firstDay = String(firstDayOfWeek.getDate()).padStart(2, '0'); const firstMonth = String(firstDayOfWeek.getMonth() + 1).padStart(2, '0'); period = `${year}-${firstMonth}-${firstDay}`; // e.g., 2025-07-12 } return `${defaultConfig.fileName.split('.')[0]}-${rotationType}-${period}.log`; } // Ensure the log directory exists function ensureLogDirectory() { const logDir = path.join(defaultConfig.logDirectory); if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } } // Function to get the full log file path, based on the dynamic file name provided by the user function getLogFilePath() { const timestamp = formatDateForFile(new Date(), defaultConfig.rotateBy); return path.join(defaultConfig.logDirectory, timestamp); } // Log rotation logic: Time-based rotation function rotateLogFile() { const logFilePath = getLogFilePath(); try { const stats = fs.existsSync(logFilePath) ? fs.statSync(logFilePath) : null; const now = new Date(); const currentPeriod = formatDateForFile(now, defaultConfig.rotateBy); // This is the current rotation period (day, month, year) const lastPeriod = stats ? formatDateForFile(new Date(stats.mtime), defaultConfig.rotateBy) : ''; // Rotation occurs only if the period has changed (daily, weekly, etc.) if (currentPeriod !== lastPeriod) { const rotatedFilePath = path.join(defaultConfig.logDirectory, currentPeriod); fs.renameSync(logFilePath, rotatedFilePath); // Rotate to a new file for the new period } } catch (err) { console.error('Error during log file rotation:', err); } } // Logging function function logIt(level, message) { // Ensure log directory exists ensureLogDirectory(); // Check if the log level is allowed (based on the current level configuration) if (levels.indexOf(level) >= levels.indexOf(defaultConfig.logLevel)) { const timestamp = formatDateForLog(new Date()); const logMessage = `${timestamp} [${level.toUpperCase()}] ${message}`; const logFilePath = getLogFilePath(); // Check if the file exists and append or create a new file if necessary if (!fs.existsSync(logFilePath)) { // Initialize the log file with the current date's name fs.writeFileSync(logFilePath, `${timestamp} [INFO] Log file created on ${timestamp}\n`); } // Rotate log file if required (based on time) rotateLogFile(); // Write the log message to the file fs.appendFileSync(logFilePath, logMessage + '\n'); // Also log to the console console.log(logMessage); } } // Allow customization of the default config function configure(options) { Object.assign(defaultConfig, options); } // Expose the logging functions (info, warn, error, debug) levels.forEach((level) => { logIt[level] = (message) => logIt(level, message); }); logIt.configure = configure; module.exports = logIt;