import { ConsoleSink } from "logger/ConsoleSink" ; import { Loggable , Logger , LogLevel } from "logger/Logger" ; import { Sink } from "logger/Sink" ; export type LoggerFactory = ( ) => Logger ; const NoopLogger = { debug ( ) { } , dispose ( ) { } , error ( ) { } , info ( ) { } , log ( ) { } , warn ( ) { } , withContext ( ) { return this ; } } ; let logLevel = LogLevel . INFO ; let logSink = new ConsoleSink ( ) ; let createLogger = ( ) => NoopLogger ; let logger = null ; let isDirty ; function getLogger ( ) { if ( isDirty || logger === null ) { if ( logger ) { logger . dispose ( ) ; } logger = createLogger ( ) ; isDirty = false ; } return logger ; } class ProxiedLogger implements Logger { private readonly context : Loggable [ ] = [ ] ; public constructor ( context ? ) { if ( context ) { this . context . push ( { context } ) ; } } public log ( logLevel , message , ... args ) { getLogger ( ) . log ( logLevel , message , ... this . context , ... args ) ; } public debug ( message , ... args ) { getLogger ( ) . debug ( message , ... this . context , ... args ) ; } public info ( message , ... args ) { getLogger ( ) . info ( message , ... this . context , ... args ) ; } public warn ( message , ... args ) { getLogger ( ) . warn ( message , ... this . context , ... args ) ; } public error ( message , ... args ) { getLogger ( ) . error ( message , ... this . context , ... args ) ; } public dispose ( ) { } public withContext ( ... args ) { const logger = new ProxiedLogger ( ) ; logger . context . push ( ... this . context , ... args ) ; return logger ; } } /**
 * Global logger factory.
 */ export class Logging { private constructor ( ) { } public static setLoggerFactory ( factory ) { createLogger = factory ; isDirty = true ; } public static getLogLevel ( ) { return logLevel ; } public static setLogLevel ( level ) { logLevel = level ; } public static getSink ( ) { return logSink ; } public static setSink ( sink ) { logSink = sink ; } /**
     * Creates a logger that will always use the settings set in this class, no matter what
     * functions are called in what order.
     */ public static getLogger ( context ? ) { return new ProxiedLogger ( context ) ; } }