UNPKG

file-error-logging

Version:

Log your errors directly to the console and to a .log file

104 lines (103 loc) 3.68 kB
// src/logger/Logger.ts import chalk from "chalk"; import fsExtra from "fs-extra"; import path from "path"; import { logToFile } from "./LogToFile"; import { formatTimestamp } from "./FormatTimestamp"; class Logger { constructor() { this.rotation = "daily"; this.development = false; this.levels = { info: { color: "blue", includeTimestampInConsole: false, defaultLogToFile: true, logFileName: "info.log", }, warn: { color: "yellowBright", includeTimestampInConsole: false, defaultLogToFile: true, logFileName: "warn.log", }, error: { color: "redBright", includeTimestampInConsole: false, defaultLogToFile: true, logFileName: "error.log", }, verbose: { color: "gray", includeTimestampInConsole: false, defaultLogToFile: true, logFileName: "verbose.log", }, }; this.logsDir = path.resolve(process.cwd(), "logs"); fsExtra.ensureDirSync(this.logsDir); } static getInstance() { if (!Logger.instance) Logger.instance = new Logger(); return Logger.instance; } setConfig(config) { this.logsDir = config.logsDir || this.logsDir; this.rotation = config.rotation || this.rotation; this.development = config.development || false; fsExtra.ensureDirSync(this.logsDir); } addLogLevel(name, { color, includeTimestampInConsole, logToFile, logFileName, onTrigger, }) { // @ts-ignore if (this.levels[name]) { // @ts-ignore If the developer wants to override an existing log level, they can do so delete this.levels[name]; } // @ts-ignore this.levels[name] = { color, includeTimestampInConsole, defaultLogToFile: logToFile, logFileName, onTrigger, }; if (logFileName) { fsExtra.ensureFileSync(path.resolve(this.logsDir, logFileName)); } } log(level, message, optionsOverride = {}) { try { // @ts-ignore const levelOptions = this.levels[level] || {}; const options = Object.assign(Object.assign({}, levelOptions), optionsOverride); // Check if the message is an object, but not an Error object if (typeof message === "object" && !(message instanceof Error)) { message = JSON.stringify(message, null, 2); } const now = new Date(); const logMessage = `${options.includeTimestampInConsole ? formatTimestamp(now) : ""} ${message}`; if (this.development) { console.log( // @ts-ignore `[${chalk[options.color || levelOptions.color](level.toUpperCase())}] - ${logMessage}`); } if (options.onTrigger) { options.onTrigger(logMessage); } if (options.logToFile || levelOptions.defaultLogToFile) { logToFile(this.logsDir, this.rotation, level, logMessage); // TODO Log to database } } catch (error) { if (error instanceof TypeError) { throw new Error(`Log level: "${level}" is not defined.`); } else { throw error; } } } } export default Logger.getInstance();