Fix DI bugs; implement general logging service

This commit is contained in:
garrettmills
2020-06-17 09:48:01 -05:00
parent 6c4696227b
commit eddb4f1fbe
13 changed files with 258 additions and 5 deletions

View File

@@ -0,0 +1,45 @@
import { LogMessage, LoggingLevel } from './types.ts'
import {make} from "../../../../di/src/global.ts";
import {Logging} from "./Logging.ts";
import {blue, cyan, gray, green, red, yellow} from "../../external/std.ts";
const isLoggerClass = (something: any): something is (typeof Logger) => {
return something.prototype instanceof Logger
}
export { isLoggerClass }
export default abstract class Logger {
public abstract async write(message: LogMessage): Promise<void>;
public static register() {
make(Logging).register_logger(this)
}
public static remove() {
make(Logging).remove_logger(this)
}
protected format_date(date: Date): string {
return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
}
protected level_display(level: LoggingLevel): string {
switch(level) {
case LoggingLevel.Success:
return green('success')
case LoggingLevel.Error:
return red('error')
case LoggingLevel.Warning:
return yellow('warning')
case LoggingLevel.Info:
return blue('info')
case LoggingLevel.Debug:
return cyan('debug')
case LoggingLevel.Verbose:
return gray('verbose')
case LoggingLevel.Silent:
return gray('silent')
}
}
}

View File

@@ -0,0 +1,74 @@
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()
class Logging {
private _level = LoggingLevel.Warning
private _loggers: Logger[] = []
public get level() {
return this._level
}
public set level(level) {
this._level = level
}
public success(output: any, force = false) {
this.write_log(LoggingLevel.Success, output, force)
}
public error(output: any, force = false) {
this.write_log(LoggingLevel.Error, output, force)
}
public warn(output: any, force = false) {
this.write_log(LoggingLevel.Warning, output, force)
}
public info(output: any, force = false) {
this.write_log(LoggingLevel.Info, output, force)
}
public debug(output: any, force = false) {
this.write_log(LoggingLevel.Debug, output, force)
}
public verbose(output: any, force = false) {
this.write_log(LoggingLevel.Verbose, output, force)
}
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 ) {
logger.write(message)
}
}
}
protected build_message(level: LoggingLevel, output: any): LogMessage {
return {
level,
output,
date: new Date,
}
}
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)
}
}
public remove_logger(logger_class: typeof Logger) {
this._loggers = this._loggers.filter(x => !(x instanceof logger_class))
}
}
export { Logging }

View File

@@ -0,0 +1,11 @@
import AbstractLogger from './Logger.ts'
import { LogMessage } from './types.ts'
import { gray } from '../../external/std.ts'
export default class StandardLogger extends AbstractLogger {
public async write(message: LogMessage): Promise<void> {
const prefix = this.level_display(message.level)
const text = `${prefix} ${gray(this.format_date(message.date))}`
console.log(text, message.output)
}
}

View File

@@ -0,0 +1,33 @@
enum LoggingLevel {
Silent = 0,
Success = 1,
Error = 1,
Warning = 2,
Info = 3,
Debug = 4,
Verbose = 5,
}
const isLoggingLevel = (something: any): something is LoggingLevel => {
return [
LoggingLevel.Silent,
LoggingLevel.Success,
LoggingLevel.Error,
LoggingLevel.Warning,
LoggingLevel.Info,
LoggingLevel.Debug,
LoggingLevel.Verbose
].includes(something)
}
interface LogMessage {
level: LoggingLevel,
date: Date,
output: any,
}
const isLogMessage = (something: any): something is LogMessage => {
return isLoggingLevel(something?.level) && something?.date instanceof Date;
}
export { LoggingLevel, LogMessage, isLoggingLevel, isLogMessage }