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  }