Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 1x 1x 1x 1x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 45x 41x 130x 7x 7x 7x 8x 10x 10x 8x 8x 44x 43x 43x 43x 43x 43x 43x 83x 43x 43x 43x 43x | /* 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);
}
}
}
|