UNPKG

n1cat-discord-script-manager

Version:

A Discord.js plugin for dynamic script management and execution

131 lines (117 loc) 3.62 kB
/** * Centralized Logger Utility * Provides consistent logging across the application */ const moment = require("moment"); class Logger { /** * Get caller information from the stack trace * @returns {Object} Caller information */ static getCallerInfo() { const stack = new Error().stack; const callerLine = stack.split("\n")[3]; const match = callerLine.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/); if (match) { const [, functionName, file, line, column] = match; return { function: functionName, file: file.split(/[/\\]/).pop(), line, column, }; } return { function: "unknown", file: "unknown", line: "unknown", column: "unknown", }; } /** * Format log message with color and context * @param {string} message - Log message * @param {Object} caller - Caller information * @param {boolean} isError - Whether it's an error message * @returns {string} Formatted log message */ static formatMessage(message, caller, isError = false) { const timestamp = moment().format("YYYY-MM-DD HH:mm:ss.SSS"); let chalk; try { chalk = require("chalk"); } catch { // Fallback to no-op coloring if chalk is not available chalk = { yellow: (text) => text, red: (text) => text, blue: (text) => text, gray: (text) => text, cyan: (text) => text, }; } return `${chalk.yellow(timestamp)} ${ isError ? chalk.red("ERROR") : chalk.blue("INFO") } ${chalk.gray(`[${caller.file}:${caller.line}]`)} ${chalk.cyan( `(${caller.function})` )} ${isError ? chalk.red(message) : message}`; } /** * Log messages with optional error handling * @param {string} message - Message to log * @param {boolean} [isError=false] - Whether it's an error message * @param {Object} [options={}] - Additional logging options */ static log(message, isError = false, options = {}) { const caller = this.getCallerInfo(); const debugMode = options.debug ?? false; if (isError || debugMode) { const formattedMessage = this.formatMessage(message, caller, isError); const logMethod = isError ? console.error : console.log; logMethod(formattedMessage); // Optional stack trace for errors if (isError && options.showStack) { let chalk; try { chalk = require("chalk"); } catch { chalk = { red: (text) => text, }; } console.error(chalk.red("Stack Trace:")); console.error(new Error().stack); } } } /** * Create a logger instance with context * @param {Object} context - Logging context * @returns {Object} Logger with context */ static createContextLogger(context) { return { log: (message, isError) => this.log(message, isError, { ...context }), error: (message, options = {}) => this.log(message, true, { ...context, showStack: options.showStack ?? true, }), debug: (message) => this.log(message, false, { ...context, debug: true }), }; } /** * Performance logging with timing * @param {string} message - Log message * @param {Function} fn - Function to measure * @returns {any} Result of the function */ static performance(message, fn) { const start = Date.now(); const result = fn(); const duration = Date.now() - start; this.log(`${message} (${duration}ms)`, false, { debug: true }); return result; } } module.exports = Logger;