package logger import ( "context" "log/slog" "os" "strings" ) type ctxKey struct{} var ( L *slog.Logger = slog.Default() logKey = ctxKey{} ) // Init 初始化全局日志 func Init(level, format string) { var handler slog.Handler opts := &slog.HandlerOptions{ Level: parseLevel(level), } if strings.ToLower(format) == "json" { handler = slog.NewJSONHandler(os.Stdout, opts) } else { handler = slog.NewTextHandler(os.Stdout, opts) } L = slog.New(handler) slog.SetDefault(L) } // FromContext 从 context 中获取 logger,如果不存在则返回全局 logger func FromContext(ctx context.Context) *slog.Logger { if l, ok := ctx.Value(logKey).(*slog.Logger); ok { return l } return L } // WithContext 将 logger 注入 context func WithContext(ctx context.Context, l *slog.Logger) context.Context { return context.WithValue(ctx, logKey, l) } func parseLevel(level string) slog.Level { switch strings.ToLower(level) { case "debug": return slog.LevelDebug case "info": return slog.LevelInfo case "warn": return slog.LevelWarn case "error": return slog.LevelError default: return slog.LevelInfo } } // 快捷方法,支持强类型 slog.Attr 或松散的 key-value 对 func Debug(msg string, args ...any) { L.Debug(msg, args...) } func Info(msg string, args ...any) { L.Info(msg, args...) } func Warn(msg string, args ...any) { L.Warn(msg, args...) } func Error(msg string, args ...any) { L.Error(msg, args...) }