You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.7 KiB
162 lines
4.7 KiB
import {LoggingLevel, LogMessage} from './types.ts'
|
|
import Logger from './Logger.ts'
|
|
import {Service} from '../../../../di/src/decorator/Service.ts'
|
|
import {make} from '../../../../di/src/global.ts'
|
|
import {isInstantiable} from '../../../../di/src/type/Instantiable.ts'
|
|
|
|
/**
|
|
* Service for managing application logging.
|
|
*/
|
|
@Service()
|
|
class Logging {
|
|
/**
|
|
* The current logging level.
|
|
* @type LoggingLevel
|
|
*/
|
|
private _level = LoggingLevel.Warning
|
|
|
|
/**
|
|
* Loggers registered with this service.
|
|
* @type Array<Logger>
|
|
*/
|
|
private _loggers: Logger[] = []
|
|
|
|
/**
|
|
* Get the current logging level.
|
|
* @type LoggingLevel
|
|
*/
|
|
public get level() {
|
|
return this._level
|
|
}
|
|
|
|
/**
|
|
* Set the new logging level.
|
|
* @param {LoggingLevel} level
|
|
*/
|
|
public set level(level) {
|
|
this._level = level
|
|
}
|
|
|
|
/**
|
|
* Write an output with the success level.
|
|
* @param output
|
|
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
|
|
*/
|
|
public success(output: any, force = false) {
|
|
this.write_log(LoggingLevel.Success, output, force)
|
|
}
|
|
|
|
/**
|
|
* Write an output with the error level.
|
|
* @param output
|
|
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
|
|
*/
|
|
public error(output: any, force = false) {
|
|
this.write_log(LoggingLevel.Error, output, force)
|
|
}
|
|
|
|
/**
|
|
* Write an output with the warning level.
|
|
* @param output
|
|
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
|
|
*/
|
|
public warn(output: any, force = false) {
|
|
this.write_log(LoggingLevel.Warning, output, force)
|
|
}
|
|
|
|
/**
|
|
* Write an output with the info level.
|
|
* @param output
|
|
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
|
|
*/
|
|
public info(output: any, force = false) {
|
|
this.write_log(LoggingLevel.Info, output, force)
|
|
}
|
|
|
|
/**
|
|
* Write an output with the debug level.
|
|
* @param output
|
|
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
|
|
*/
|
|
public debug(output: any, force = false) {
|
|
this.write_log(LoggingLevel.Debug, output, force)
|
|
}
|
|
|
|
/**
|
|
* Write an output with the verbose level.
|
|
* @param output
|
|
* @param {boolean} [force = false] - if true, the output will be written, regardless of the output level
|
|
*/
|
|
public verbose(output: any, force = false) {
|
|
this.write_log(LoggingLevel.Verbose, output, force)
|
|
}
|
|
|
|
/**
|
|
* Writes the output at the given logging level.
|
|
* @param {LoggingLevel} level
|
|
* @param output
|
|
* @param {boolean} [force = false]
|
|
*/
|
|
protected write_log(level: LoggingLevel, output: any, force = false) {
|
|
const message = this.build_message(level, output)
|
|
if ( this._level >= level || force ) {
|
|
for ( const logger of this._loggers ) {
|
|
try {
|
|
logger.write(message)
|
|
} catch (e) {
|
|
console.error('logging error', e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Given an output and level, build a log message object.
|
|
* @param {LoggingLevel} level
|
|
* @param output
|
|
* @return LogMessage
|
|
*/
|
|
protected build_message(level: LoggingLevel, output: any): LogMessage {
|
|
return {
|
|
level,
|
|
output,
|
|
date: new Date,
|
|
caller_name: this.get_caller_info(),
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register a logger with this class.
|
|
* @param {typeof Logger} logger_class
|
|
*/
|
|
public register_logger(logger_class: typeof Logger) {
|
|
if ( isInstantiable(logger_class) ) {
|
|
const logger = make(logger_class)
|
|
if ( !this._loggers.includes(logger) )
|
|
this._loggers.push(logger)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove a logger from this class.
|
|
* @param {typeof Logger} logger_class
|
|
*/
|
|
public remove_logger(logger_class: typeof Logger) {
|
|
this._loggers = this._loggers.filter(x => !(x instanceof logger_class))
|
|
}
|
|
|
|
/**
|
|
* Get the information about the caller of a given context.
|
|
* @param {number} [level = 5] - how far up in the stacktrace to go
|
|
*/
|
|
protected get_caller_info(level = 5): string {
|
|
let e = new Error
|
|
if ( !e.stack ) return 'Unknown'
|
|
return e.stack.split(' at ')
|
|
.slice(level)
|
|
.map((x: string): string => x.trim().split(' (')[0].split('.')[0].split(':')[0])[0]
|
|
}
|
|
}
|
|
|
|
export { Logging }
|