diff --git a/modules/debugger.mjs b/modules/debugger.mjs index 8a3f524..c43e13f 100644 --- a/modules/debugger.mjs +++ b/modules/debugger.mjs @@ -1,25 +1,35 @@ // Import necessary modules import debug from 'debug'; import { config } from 'dotenv'; -import { writeFile } from 'fs'; +config(); +import { promises as fs } from 'fs'; +import { join, dirname } from 'path'; import { inspect } from 'util'; -// Load environment variables -config(); - -const logLocation = process.env.LOG_LOCATION; - +/** + * Write a given message to the log file + * @param {any} logMessage The message to write to the log file + * @param {string} appName The app name that created the log entry + */ const writeToLog = async (logMessage, appName) => { + const logLocation = join(process.env.LOG_LOCATION ?? `./logs/${appName}.log`); + + // Ensure the log directory exists + try { + await fs.mkdir(dirname(logLocation), { recursive: true }); + } catch (err) { + console.error(err); + } + + // Ensure the message is a string logMessage = `${String(logMessage)}\n`; - writeFile( - logLocation ?? `./${appName}.log`, - logMessage, - { encoding: "utf-8", flag: 'a+' }, - (err) => { - if (err) console.error(err); - } - ); + // Write to the file + try { + await fs.writeFile(logLocation, logMessage, { encoding: 'utf-8', flag: 'a+' }); + } catch (err) { + console.error(err); + } }; /** @@ -30,37 +40,31 @@ const writeToLog = async (logMessage, appName) => { */ export class DebugBuilder { constructor(appName, fileName) { - this.INFO = (...messageParts) => { - const _info = debug(`${appName}:${fileName}:INFO`); - _info(messageParts); - writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:INFO\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName); - }; - - this.DEBUG = (...messageParts) => { - const _debug = debug(`${appName}:${fileName}:DEBUG`); - _debug(messageParts); - writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:DEBUG\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName); - }; - - this.VERBOSE = (...messageParts) => { - const _verbose = debug(`${appName}:${fileName}:VERBOSE`); - _verbose(messageParts); - writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:VERBOSE\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName); - }; - - this.WARN = (...messageParts) => { - const _warn = debug(`${appName}:${fileName}:WARNING`); - _warn(messageParts); - writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:WARNING\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName); + const buildLogger = (level) => (...messageParts) => { + const logger = debug(`${appName}:${fileName}:${level}`); + logger(messageParts); + + const timeStamp = new Date().toLocaleString('en-US', { timeZone: 'America/New_York' }); + const message = `${timeStamp} - ${appName}:${fileName}:${level}\t-\t${messageParts.map(part => inspect(part)).join(' ')}`; + + // Write to console + console.log(message); + + // Write to logfile + writeToLog(message, appName); }; + this.INFO = buildLogger('INFO'); + this.DEBUG = buildLogger('DEBUG'); + this.VERBOSE = buildLogger('VERBOSE'); + this.WARN = buildLogger('WARNING'); this.ERROR = (...messageParts) => { - const _error = debug(`${appName}:${fileName}:ERROR`); - _error(messageParts); - writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:ERROR\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName); + buildLogger('ERROR')(...messageParts); + if (process.env.EXIT_ON_ERROR && process.env.EXIT_ON_ERROR > 0) { writeToLog("!--- EXITING ---!", appName); - setTimeout(() => process.exit(), process.env.EXIT_ON_ERROR_DELAY ?? 0); + const exitDelay = parseInt(process.env.EXIT_ON_ERROR_DELAY, 10) || 0; + setTimeout(() => process.exit(1), exitDelay); } }; }