// Package logger define log struct of modelRT project package logger import ( "context" "path" "runtime" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) type logger struct { ctx context.Context traceID string spanID string pSpanID string _logger *zap.Logger } func (l *logger) Debug(msg string, kv ...any) { l.log(zapcore.DebugLevel, msg, kv...) } func (l *logger) Info(msg string, kv ...any) { l.log(zapcore.InfoLevel, msg, kv...) } func (l *logger) Warn(msg string, kv ...any) { l.log(zapcore.WarnLevel, msg, kv...) } func (l *logger) Error(msg string, kv ...any) { l.log(zapcore.ErrorLevel, msg, kv...) } func (l *logger) log(lvl zapcore.Level, msg string, kv ...any) { fields := makeLogFields(l.ctx, kv...) ce := l._logger.Check(lvl, msg) ce.Write(fields...) } func makeLogFields(ctx context.Context, kv ...any) []zap.Field { // Ensure that log information appears in pairs in the form of key-value pairs if len(kv)%2 != 0 { kv = append(kv, "unknown") } kv = append(kv, "traceID", ctx.Value("traceID"), "spanID", ctx.Value("spanID"), "pspanID", ctx.Value("pspanID")) funcName, file, line := getLoggerCallerInfo() kv = append(kv, "func", funcName, "file", file, "line", line) fields := make([]zap.Field, 0, len(kv)/2) for i := 0; i < len(kv); i += 2 { key := kv[i].(string) value := kv[i+1] switch v := value.(type) { case string: fields = append(fields, zap.String(key, v)) case int: fields = append(fields, zap.Int(key, v)) case int64: fields = append(fields, zap.Int64(key, v)) case float32: fields = append(fields, zap.Float32(key, v)) case float64: fields = append(fields, zap.Float64(key, v)) case bool: fields = append(fields, zap.Bool(key, v)) case error: fields = append(fields, zap.Error(v)) default: fields = append(fields, zap.Any(key, v)) } } return fields } // getLoggerCallerInfo define func of return log caller information、method name、file name、line number func getLoggerCallerInfo() (funcName, file string, line int) { pc, file, line, ok := runtime.Caller(4) if !ok { return } file = path.Base(file) funcName = runtime.FuncForPC(pc).Name() return } func New(ctx context.Context) *logger { var traceID, spanID, pSpanID string if ctx.Value("traceID") != nil { traceID = ctx.Value("traceID").(string) } if ctx.Value("spanID") != nil { spanID = ctx.Value("spanID").(string) } if ctx.Value("psapnID") != nil { pSpanID = ctx.Value("pspanID").(string) } return &logger{ ctx: ctx, traceID: traceID, spanID: spanID, pSpanID: pSpanID, _logger: GetLoggerInstance(), } }