github.com/wfusion/gofusion@v1.1.14/log/customlogger/async.go (about) 1 package customlogger 2 3 import ( 4 "context" 5 "reflect" 6 "strings" 7 8 "github.com/spf13/cast" 9 10 "github.com/wfusion/gofusion/common/infra/asynq" 11 "github.com/wfusion/gofusion/config" 12 "github.com/wfusion/gofusion/log" 13 ) 14 15 var ( 16 // AsyncLoggerType FIXME: should not be deleted to avoid compiler optimized 17 AsyncLoggerType = reflect.TypeOf(asyncLogger{}) 18 asyncFields = log.Fields{"component": strings.ToLower(config.ComponentAsync)} 19 ) 20 21 func DefaultAsyncLogger() interface{ Printf(string, ...any) } { 22 return &asyncLogger{} 23 } 24 25 func DefaultAsynqAsyncLogger() asynq.Logger { 26 return &asyncLogger{} 27 } 28 29 type asyncLogger struct { 30 log log.Loggable 31 appName string 32 confName string 33 enabled bool 34 } 35 36 func (a *asyncLogger) Init(log log.Loggable, appName, confName string) { 37 a.log = log 38 a.appName = appName 39 a.confName = confName 40 a.reloadConfig() 41 } 42 43 func (a *asyncLogger) Printf(format string, args ...any) { 44 if !a.isLoggable() { 45 return 46 } 47 a.logger().Info(context.Background(), format, append(args, asyncFields)...) 48 } 49 50 // Debug logs a message at Debug level. 51 func (a *asyncLogger) Debug(args ...any) { 52 if !a.isLoggable() { 53 return 54 } 55 ctx, format, args := a.parseArgs(args...) 56 a.logger().Debug(ctx, format, args...) 57 } 58 59 // Info logs a message at Info level. 60 func (a *asyncLogger) Info(args ...any) { 61 if !a.isLoggable() { 62 return 63 } 64 ctx, format, args := a.parseArgs(args...) 65 a.logger().Info(ctx, format, args...) 66 } 67 68 // Warn logs a message at Warning level. 69 func (a *asyncLogger) Warn(args ...any) { 70 if !a.isLoggable() { 71 return 72 } 73 ctx, format, args := a.parseArgs(args...) 74 a.logger().Warn(ctx, format, args...) 75 } 76 77 // Error logs a message at Error level. 78 func (a *asyncLogger) Error(args ...any) { 79 if !a.isLoggable() { 80 return 81 } 82 ctx, format, args := a.parseArgs(args...) 83 a.logger().Error(ctx, format, args...) 84 } 85 86 // Fatal logs a message at Fatal level 87 // and process will exit with status set to 1. 88 func (a *asyncLogger) Fatal(args ...any) { 89 if !a.isLoggable() { 90 return 91 } 92 ctx, format, args := a.parseArgs(args...) 93 a.logger().Fatal(ctx, format, args...) 94 } 95 96 func (a *asyncLogger) logger() log.Loggable { 97 if a.log != nil { 98 return a.log 99 } 100 return log.Use(config.DefaultInstanceKey, log.AppName(a.appName)) 101 } 102 103 // parseArgs support (ctx, format, args...) log format 104 func (a *asyncLogger) parseArgs(args ...any) (ctx context.Context, format string, params []any) { 105 var ok bool 106 107 if len(args) == 0 { 108 return context.Background(), "", []any{asyncFields} 109 } 110 if len(args) == 1 { 111 args = append(args, asyncFields) 112 return context.Background(), "%+v", args 113 } 114 115 format, ok = args[0].(string) 116 if ok { 117 params = args[1:] 118 } else { 119 ctx, _ = args[0].(context.Context) 120 format, _ = args[1].(string) 121 params = args[2:] 122 } 123 if format == "" { 124 placeholder := make([]string, len(args)) 125 for i := 0; i < len(args); i++ { 126 placeholder[i] = "%+v" 127 } 128 format = strings.Join(placeholder, " ") 129 params = args 130 } 131 132 if ctx == nil { 133 ctx = context.Background() 134 } 135 136 params = append(params, asyncFields) 137 return 138 } 139 140 func (a *asyncLogger) isLoggable() bool { 141 if a.confName == "" { 142 return true 143 } 144 a.reloadConfig() 145 return a.enabled 146 } 147 148 func (a *asyncLogger) reloadConfig() { 149 var cfgs map[string]map[string]any 150 _ = config.Use(a.appName).LoadComponentConfig(config.ComponentAsync, &cfgs) 151 if len(cfgs) == 0 { 152 return 153 } 154 155 cfg, ok := cfgs[a.confName] 156 if !ok { 157 return 158 } 159 enabled := cast.ToBool(cfg["enable_logger"]) 160 a.enabled = enabled 161 }