import {Logger, LoggingLevel, LogMessage} from "@extollo/util"; import {Singleton} from "@extollo/di"; @Singleton() export class Logging { protected registeredLoggers: Logger[] = [] protected currentLevel: LoggingLevel = LoggingLevel.Warning public registerLogger(logger: Logger) { if ( !this.registeredLoggers.includes(logger) ) { this.registeredLoggers.push(logger) } } public unregisterLogger(logger: Logger) { this.registeredLoggers = this.registeredLoggers.filter(x => x !== logger) } public get level(): LoggingLevel { return this.currentLevel } public set level(level: LoggingLevel) { this.currentLevel = level } public success(output: any, force = false) { this.writeLog(LoggingLevel.Success, output, force) } public error(output: any, force = false) { this.writeLog(LoggingLevel.Error, output, force) } public warn(output: any, force = false) { this.writeLog(LoggingLevel.Warning, output, force) } public info(output: any, force = false) { this.writeLog(LoggingLevel.Info, output, force) } public debug(output: any, force = false) { this.writeLog(LoggingLevel.Debug, output, force) } public verbose(output: any, force = false) { this.writeLog(LoggingLevel.Verbose, output, force) } protected writeLog(level: LoggingLevel, output: any, force = false) { const message = this.buildMessage(level, output) if ( this.currentLevel >= level || force ) { for ( const logger of this.registeredLoggers ) { try { logger.write(message) } catch (e) { console.error('logging error', e) } } } } protected buildMessage(level: LoggingLevel, output: any): LogMessage { return { level, output, date: new Date, callerName: this.getCallerInfo(), } } protected getCallerInfo(level = 5): string { const e = new Error() if ( !e.stack ) return 'Unknown' return e.stack.split(/\s+at\s+/) .slice(level) .map((x: string): string => x.trim().split(' (')[0].split('.')[0].split(':')[0])[0] .split('/') .reverse()[0] } }