// Package logger provider std slog logger package logger import ( "io" "log/slog" "os" "path/filepath" "strconv" "gopkg.in/natefinch/lumberjack.v2" "git.ifooth.com/common/pkg/config" ) // Init 初始化 slog func Init() { textHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ AddSource: true, Level: slog.LevelInfo, ReplaceAttr: ReplaceSourceAttr, }) logger := slog.New(textHandler) slog.SetDefault(logger) } // GetLevelByName human readable logger level func GetLevelByName(name string) slog.Level { switch name { case "error": return slog.LevelError case "warn": return slog.LevelWarn case "info": return slog.LevelInfo case "debug": return slog.LevelDebug default: return slog.LevelInfo } } // NewLogger make a new logger func NewLogger(opts *config.LogConf) *slog.Logger { handler := NewHandler(opts) logger := slog.New(handler) return logger } // NewHandler make a new handler func NewHandler(opts *config.LogConf) slog.Handler { ioWriter := io.Discard if opts.Stdout { ioWriter = os.Stdout } if opts.FileName != "" { fileWriter := &lumberjack.Logger{ Filename: opts.FileName, MaxSize: opts.MaxSize, MaxBackups: opts.MaxNum, LocalTime: true, Compress: false, } if ioWriter == io.Discard { ioWriter = fileWriter } else { ioWriter = io.MultiWriter(ioWriter, fileWriter) } } level := GetLevelByName(opts.Level) slogOpt := &slog.HandlerOptions{ AddSource: true, Level: level, ReplaceAttr: ReplaceSourceAttr, } if opts.Format == "json" { return slog.NewJSONHandler(ioWriter, slogOpt) } return slog.NewTextHandler(ioWriter, slogOpt) } // ReplaceSourceAttr source 格式化为 dir/file:line 格式 func ReplaceSourceAttr(groups []string, a slog.Attr) slog.Attr { if a.Key != slog.SourceKey { return a } src, ok := a.Value.Any().(*slog.Source) if !ok { return a } a.Value = slog.StringValue(filepath.Base(src.File) + ":" + strconv.Itoa(src.Line)) return a }