github.com/Aoi-hosizora/ahlib@v1.5.1-0.20230404072829-241b93cf91c7/xmodule/xmodule_logger.go (about) 1 package xmodule 2 3 import ( 4 "fmt" 5 "github.com/Aoi-hosizora/ahlib/xcolor" 6 ) 7 8 // LogLevel represents ModuleContainer's logger level. 9 type LogLevel uint8 10 11 const ( 12 // LogPrvName logs when ModuleContainer.ProvideByName invoked. 13 LogPrvName LogLevel = 1 << iota 14 15 // LogPrvType logs when ModuleContainer.ProvideByType invoked. 16 LogPrvType 17 18 // LogPrvIntf logs when ModuleContainer.ProvideByIntf invoked. 19 LogPrvIntf 20 21 // LogInjField logs when ModuleContainer.Inject invoked and some fields are injected. 22 LogInjField 23 24 // LogInjFinish logs when ModuleContainer.Inject invoked and injecting is finished. 25 LogInjFinish 26 27 // LogPrv logs when ModuleContainer.ProvideByName, ModuleContainer.ProvideByType and ModuleContainer.ProvideByIntf invoked. 28 LogPrv = LogPrvName | LogPrvType | LogPrvIntf 29 30 // LogAll logs when ModuleContainer.ProvideByName, ModuleContainer.ProvideByType, ModuleContainer.ProvideByIntf and ModuleContainer.Inject invoked. 31 LogAll = LogPrvName | LogPrvType | LogPrvIntf | LogInjField | LogInjFinish 32 33 // LogSilent never logs, means disable the logger. 34 LogSilent = LogLevel(0) 35 ) 36 37 // Logger represents ModuleContainer's logger interface, a default logger can be created by DefaultLogger. 38 type Logger interface { 39 // PrvName logs when ModuleContainer.ProvideByName invoked, can be enabled by LogPrvName flag. 40 PrvName(moduleName, moduleType string) 41 42 // PrvType logs when ModuleContainer.ProvideByType invoked, can be enabled by LogPrvType flag. 43 PrvType(moduleType string) 44 45 // PrvIntf logs when ModuleContainer.ProvideByIntf invoked, can be enabled by LogPrvIntf flag. 46 PrvIntf(interfaceType, moduleType string) 47 48 // InjField logs when ModuleContainer.Inject invoked and some fields are injected, can be enabled by LogInjField flag. 49 InjField(moduleName, injecteeType, fieldName, fieldType string) 50 51 // InjFinish logs when ModuleContainer.Inject invoked and injecting is finished, can be enabled by LogInjFinish flag. 52 InjFinish(injecteeType string, injectedCount, totalCount int) 53 } 54 55 // defaultLogger represents an unexported default Logger type. 56 type defaultLogger struct { 57 level LogLevel 58 logPrvFunc func(moduleName, moduleType string) 59 logInjFunc func(moduleName, injecteeType, addition string) 60 } 61 62 var _ Logger = (*defaultLogger)(nil) 63 64 // DefaultLogger creates a default Logger instance, with given LogLevel, nillable logPrjFunc and logInjFunc. 65 // 66 // The default format for providing logs like: 67 // [Xmodule] Prv: int <-- int 68 // [Xmodule] Prv: ~ <-- float64 69 // [Xmodule] Prv: ~ <-- error (*errors.errorString) 70 // |--------------------| |---------------------------| 71 // 20 ... 72 // 73 // The default format for injecting logs like: 74 // [Xmodule] Inj: uint --> *xmodule.testStruct (Uint: uint) 75 // [Xmodule] Inj: ~ --> *xmodule.testStruct (String: string) 76 // [Xmodule] Inj: ~ --> *xmodule.testStruct (Error: error) 77 // [Xmodule] Inj: ... --> *xmodule.testStruct (#=6/6, all injected) 78 // [Xmodule] Inj: ... --> *xmodule.testStruct (#=4/6, partially injected) 79 // |--------------------| |-------------------|---------------------------| 80 // 20 ... ... 81 func DefaultLogger(level LogLevel, logPrvFunc func(moduleName, moduleType string), logInjFunc func(moduleName, injecteeType, addition string)) Logger { 82 xcolor.ForceColor() 83 if logPrvFunc == nil { 84 logPrvFunc = func(moduleName, moduleType string) { 85 fmt.Printf( 86 "[Xmodule] Prv: %s <-- %s\n", 87 xcolor.Red.ASprint(-20, moduleName), xcolor.Yellow.Sprint(moduleType), 88 ) 89 } 90 } 91 if logInjFunc == nil { 92 logInjFunc = func(moduleName, injecteeType, addition string) { 93 fmt.Printf( 94 "[Xmodule] Inj: %s --> %s %s\n", 95 xcolor.Red.ASprint(-20, moduleName), xcolor.Blue.Sprint(injecteeType), xcolor.Yellow.Sprintf("(%s)", addition), 96 ) 97 } 98 } 99 return &defaultLogger{level: level, logPrvFunc: logPrvFunc, logInjFunc: logInjFunc} 100 } 101 102 // PrvName logs when ModuleContainer.ProvideByName or ModuleContainer.AutoProvide invoked, can be enabled by LogPrvName flag. 103 // 104 // The default format logs like: 105 // [Xmodule] Prv: xxx-tag <-- *Module 106 // |-------| |-------| 107 // red yellow 108 // Here `xxx-tag` is module name, `*Module` is module type. 109 func (d *defaultLogger) PrvName(moduleName, moduleType string) { 110 if d.level&LogPrvName != 0 { 111 d.logPrvFunc(moduleName, moduleType) 112 } 113 } 114 115 // PrvType logs when ModuleContainer.ProvideByType or ModuleContainer.AutoProvide invoked, can be enabled by LogPrvType flag. 116 // 117 // The default format logs like: 118 // [Xmodule] Prv: ~ <-- *Module 119 // |-| |-------| 120 // red yellow 121 // Here `~` is module name (means provide by type or intf), `*Module` is module type. 122 func (d *defaultLogger) PrvType(moduleType string) { 123 if d.level&LogPrvType != 0 { 124 d.logPrvFunc("~", moduleType) 125 } 126 } 127 128 // PrvIntf logs when ModuleContainer.ProvideByIntf or ModuleContainer.AutoProvide invoked, can be enabled by LogInjField flag. 129 // 130 // The default format logs like: 131 // [Xmodule] Prv: ~ <-- IModule (*Module) 132 // |-| |-----------------| 133 // red yellow 134 // Here `~` is module name (means provide by type or intf), `IModule` is interface type, `*Module` is implemented module type. 135 func (d *defaultLogger) PrvIntf(interfaceType, moduleType string) { 136 if d.level&LogPrvIntf != 0 { 137 d.logPrvFunc("~", fmt.Sprintf("%s (%s)", interfaceType, moduleType)) 138 } 139 } 140 141 // InjField logs when ModuleContainer.Inject invoked and some fields are injected, can be enabled by LogInjField flag. 142 // 143 // The default format logs like: 144 // [Xmodule] Inj: xxx-tag --> *Struct (Field: string) 145 // [Xmodule] Inj: ~ --> *Struct (Field: string) 146 // |-------| |-------|---------------| 147 // red blue yellow 148 // Here `xxx-tag` or `~` is module name, `*Struct` is injectee type, `Field` is injectee field name, `string` is field type. 149 func (d *defaultLogger) InjField(moduleName, injecteeType, fieldName, fieldType string) { 150 if d.level&LogInjField != 0 { 151 d.logInjFunc(moduleName, injecteeType, fmt.Sprintf("%s: %s", fieldName, fieldType)) 152 } 153 } 154 155 // InjFinish logs when ModuleContainer.Inject invoked and injecting is finished, can be enabled by LogInjFinish flag. 156 // 157 // The default format logs like: 158 // [Xmodule] Inj: ... --> *Struct (#=3/3, all injected) 159 // [Xmodule] Inj: ... --> *Struct (#=2/3, partially injected) 160 // |---| |-------|---------------------------| 161 // red blue yellow 162 // Here `...` means injecting is finished, `*Struct` is injectee type, `#=3/3` is injected and total fields count, `all injected` 163 // and `partially injected` means whether all module fields are injected or not. 164 func (d *defaultLogger) InjFinish(injecteeType string, injectedCount, totalCount int) { 165 if d.level&LogInjFinish != 0 { 166 flag := "all injected" 167 if injectedCount != totalCount { 168 flag = "partially injected" 169 } 170 d.logInjFunc("...", injecteeType, fmt.Sprintf("#=%d/%d, %s", injectedCount, totalCount, flag)) 171 } 172 }