UNPKG

@evojs/logger

Version:
199 lines (198 loc) 5.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Logger = void 0; /* eslint-disable lodash/prefer-lodash-typecheck */ const context_1 = require("@evojs/context"); const data_to_table_function_1 = require("./data-to-table.function"); const enums_1 = require("./enums"); const log_1 = require("./log"); const LOG_LEVELS = Object.values(enums_1.LogLevel); const DEFAULT_LEVEL = enums_1.LogLevel.INFO; class Logger { /** * Create new Logger with custom options */ constructor(options = {}) { this._pipes = {}; this._startTimes = {}; const { name = Logger.logname, formats = Logger._formats, handler = Logger._handler, logLevel, callsiteDepth, } = options; this.logname = name; this._formats = formats; this._handler = handler; this._callsiteDepth = callsiteDepth ?? Logger._callsiteDepth; this._loglevelindex = logLevel ? LOG_LEVELS.indexOf(logLevel) : Logger._loglevelindex; Object.assign(this._pipes, Logger._pipes, options.pipes); } setName(nameOrConstructor) { const logger = this.clone(); const name = typeof nameOrConstructor === 'function' ? nameOrConstructor.name : nameOrConstructor; // @ts-ignore logger.logname = [logger.logname, name].filter(Boolean).join('.'); return logger; } /** * Create a new logger with options of current logger. */ clone() { return new Logger({ name: this.logname, formats: this._formats, pipes: this._pipes, handler: this._handler, logLevel: LOG_LEVELS[this._loglevelindex], callsiteDepth: this._callsiteDepth, }); } /** * Create fatal log. */ fatal(...args) { Logger.fatal.apply(this, args); } /** * Create error log. */ error(...args) { Logger.error.apply(this, args); } /** * Create warn log. */ warn(...args) { Logger.warn.apply(this, args); } /** * Create info log. */ info(...args) { Logger.info.apply(this, args); } /** * Create debug log. Enable debug for working. */ debug(...args) { Logger.debug.apply(this, args); } /** * Create verbose log. */ verbose(...args) { Logger.verbose.apply(this, args); } /** * Create verbose log. */ log(level, name, ...args) { Logger.log.call(this, level, name, ...args); } table(...args) { Logger.table.apply(this, args); } start(label, level) { Logger.start.call(this, label, level); } end(label, level) { Logger.end.call(this, label, level); } static _handle(level, args, logname = this.logname) { if (LOG_LEVELS.indexOf(level) > this._loglevelindex) { return; } if (Logger._handling) { process.nextTick(Logger._handle.bind(this), this, level, args, logname); return; } Logger._handling = true; const { _formats, _pipes, _handler, _callsiteDepth } = this; try { const log = new log_1.Log(logname, _formats, _pipes, level, args, _callsiteDepth); _handler.call(this, log); } catch (err) { console.error(err); process.exit(1); } Logger._handling = false; } /** * Set global options. */ static configure(options) { this.logname = options.name || ''; this._callsiteDepth = options.callsiteDepth; if (Array.isArray(options.formats)) { this._formats.splice(0, this._formats.length, ...options.formats); } if (typeof options.handler === 'function') { this._handler = options.handler; } Object.assign(this._pipes, options.pipes); this._loglevelindex = LOG_LEVELS.indexOf(options.logLevel || enums_1.LogLevel.VERBOSE); } static setName(nameOrConstructor) { const name = typeof nameOrConstructor === 'function' ? nameOrConstructor.name : nameOrConstructor; const logname = [this.logname, name].filter(Boolean).join('.'); return new this({ name: logname }); } static fatal(...args) { Logger._handle.call(this, enums_1.LogLevel.FATAL, args); } static error(...args) { Logger._handle.call(this, enums_1.LogLevel.ERROR, args); } static warn(...args) { Logger._handle.call(this, enums_1.LogLevel.WARN, args); } static info(...args) { Logger._handle.call(this, enums_1.LogLevel.INFO, args); } static debug(...args) { Logger._handle.call(this, enums_1.LogLevel.DEBUG, args); } static verbose(...args) { Logger._handle.call(this, enums_1.LogLevel.VERBOSE, args); } static log(level, name = this.logname, ...args) { Logger._handle.call(this, level, args, name); } static table(...args) { const [arg0, arg1, arg2] = args; const [message, values, level] = (typeof arg0 === 'string' ? [arg0, arg1, arg2 || DEFAULT_LEVEL] : [undefined, arg0, arg1 || DEFAULT_LEVEL]); const table = (0, data_to_table_function_1.dataToTable)(values); Logger._handle.call(this, level, message ? [message, table] : [table]); } static start(label, level = DEFAULT_LEVEL) { const asyncContext = context_1.AsyncContext.get(); if (!asyncContext) { throw new Error(`AsyncContext is not available`); } const { traceId } = asyncContext; this._startTimes[`${label}_${traceId}`] = process.hrtime.bigint(); Logger._handle.call(this, level, [`Start of '${label}'`]); } static end(label, level = DEFAULT_LEVEL) { const asyncContext = context_1.AsyncContext.get(); if (!asyncContext) { throw new Error(`AsyncContext is not available`); } const { traceId } = asyncContext; const startTime = this._startTimes[`${label}_${traceId}`]; if (!startTime) { throw new Error(`No such label '${label}' for Logger#end`); } const endTime = process.hrtime.bigint(); const delta = Number((endTime - startTime) / 1000000n); delete this._startTimes[`${label}_${traceId}`]; Logger._handle.call(this, level, [`End of '${label}' (${delta}ms)`]); } } exports.Logger = Logger; Logger.logname = ''; Logger._pipes = {}; Logger._formats = []; Logger._startTimes = {}; Logger._loglevelindex = LOG_LEVELS.indexOf(enums_1.LogLevel.VERBOSE); Logger._handling = false; Logger._handler = (log) => { };