UNPKG

@node-dlc/logger

Version:
148 lines (126 loc) 3.63 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import util from 'util'; import { LogLevel } from './log-level'; import { ITransport } from './transport'; import { shouldLog } from './util'; export interface ILogger { area: string; instance: string; trace(...args: any[]): void; debug(...args: any[]): void; info(...args: any[]): void; warn(...args: any[]): void; error(...args: any[]): void; sub(area: string, instance?: string): ILogger; } export class Logger implements ILogger { public readonly area: string; public readonly instance: string; private _transports: ITransport[]; private _level: LogLevel; private _root: Logger; constructor(area = '', instance?: string) { this._root = this; this.area = area; this.instance = instance; this._level = LogLevel.Info; this._transports = []; // create bound methods so consumer doesnt lose context this.trace = this.trace.bind(this); this.debug = this.debug.bind(this); this.info = this.info.bind(this); this.warn = this.warn.bind(this); this.error = this.error.bind(this); } /** * Configured log-level */ get level(): LogLevel { return this._root._level; } set level(value: LogLevel) { this._root._level = value; } /** * Gets the available transports */ get transports(): ITransport[] { return this._root._transports; } /** * Constructs a sub-logger under the current parent * @param area optional area, if not provided it inherits from the parent * @param instance optional instance, if not provied it inherits from the parent */ public sub(area?: string, instance?: string): Logger { const logger = new Logger(area || this.area, instance || this.instance); logger._root = this._root; return logger; } /** * Write a trace message */ public trace(...args: any[]): void { this._log(LogLevel.Trace, this.area, this.instance, args); } /** * Write a debug message * @param args variadic arguments */ public debug(...args: any[]): void { this._log(LogLevel.Debug, this.area, this.instance, args); } /** * Write an info message * @param args variadic arguments */ public info(...args: any[]): void { this._log(LogLevel.Info, this.area, this.instance, args); } /** * Write a warning message * @param args variadic arguments */ public warn(...args: any[]): void { this._log(LogLevel.Warn, this.area, this.instance, args); } /** * Write an error message * @param args variadic arguments */ public error(...args: any[]): void { this._log(LogLevel.Error, this.area, this.instance, args); } ///////////////////////////// private _log( level: LogLevel, area: string, instance: string, args: any[], ): void { if (!shouldLog(this.level, level)) return; const formattedMsg = this._format(level, area, instance, args); this._write(formattedMsg); } private _format( level: LogLevel, area: string, instance: string, args: any[], ): string { const date = new Date().toISOString(); const formattedArea = area ? ' ' + area : ''; const instanceFmt = instance ? ' ' + instance : ''; // convert buffers to hex encodings args = args.map((arg) => Buffer.isBuffer(arg) ? arg.toString('hex') : arg, ); const msg = util.format(args[0], ...args.slice(1)); return `${date} [${level}]${formattedArea}${instanceFmt}: ${msg}`; } private _write(msg: string): void { for (const transport of this._root.transports) { transport.write(msg); } } }