import debugFn from 'debug' ; import { EventEmitter } from 'events' ; import { isPlainObject } from './deps' ; import { toString , isString , trimAndToLower } from './strings' ; import { Logger } from './logger-interface' ; import { uniq } from './arrays' ; import { isTest } from './env' ; interface DebugParamObj { module : string ; assignment ? : string ; [ name ] : any ; } type DebugParam = DebugParamObj | string ; let logLevel = process . env . DEBUG_LOG_LEVEL || 'debug' ; const levels = { trace : 10 , debug : 20 , info : 30 , warn : 40 , error : 50 , fatal : 60 , } ; export function debugLogger ( testName , param ? , otherName ? ) { const logger = new EventEmitter ( ) as Logger ; let parts = testName ? testName . split ( ':' ) : [ ] ; if ( param ) { if ( isString ( param ) ) { parts . push ( param as string ) ; } else if ( typeof param === 'object' ) { parts . push ( param . module ) ; if ( param . assignment ) { parts . push ( param . assignment ) ; } } } if ( otherName ) { parts . push ( otherName ) ; } parts = parts . map ( toString ) . map ( trimAndToLower ) ; parts = uniq ( parts . filter ( ( str ) => ! ! str ) ) ; if ( ! parts . includes ( 'teraslice' ) ) { parts . unshift ( 'teraslice' ) ; } const name = parts . join ( ':' ) ; logger . streams = [ ] ; logger . addStream = ( ) => { } ; logger . child = ( opts , _simple ? ) : Logger => { if ( isString ( opts ) ) { return debugLogger ( name , undefined , opts ) ; } if ( isPlainObject ( opts ) ) { return debugLogger ( name , opts as DebugParam , opts . module ) ; } return debugLogger ( name , opts as DebugParam ) ; } ; logger . flush = async ( ) => true ; logger . reopenFileStreams = ( ) => { } ; logger . src = false ; logger . level = ( value ) : number | undefined => { if ( value ) { for ( const [ level , code ] of Object . entries ( levels ) ) { if ( value === level || value === code ) { logLevel = level ; return undefined ; } } return undefined ; } return levels [ logLevel ] || 20 ; } ; logger . levels = ( ) => logger . level ( ) ; for ( const [ level , code ] of Object . entries ( levels ) ) { const fLevel = `[${ level . toUpperCase ( ) }]` ; const debug = debugFn ( name ) ; logger [ level ] = ( ... args ) => { if ( code < logger . level ( ) ) return false ; if ( level === 'fatal' && ! isTest ) { console . error ( `${ name } ${ fLevel }` , ... args ) ; return true ; } debug ( fLevel , ... args ) ; return true ; } ; } return logger ; } export { Logger } ;