Viewing:
    
  package logging
import (
	"context"
	"log/slog"
	"net/http"
	"os"
	"time"
)
type logKeyType struct{}
var logKey = logKeyType{}
func FromReq(r *http.Request) *slog.Logger {
	return FromCtx(r.Context())
}
func ToReq(r *http.Request, newLog *slog.Logger) *http.Request {
	return r.WithContext(context.WithValue(r.Context(), logKey, newLog))
}
func FromCtx(c context.Context) *slog.Logger {
	val := c.Value(logKey)
	log, ok := val.(*slog.Logger)
	if !ok {
		log = New()
		log.Warn("Log not configured. Likely a code error.")
	}
	return log
}
func replaceLogAttrs(groups []string, a slog.Attr) slog.Attr {
	if a.Key == slog.TimeKey && len(groups) == 0 {
		return slog.Int64("at", a.Value.Any().(time.Time).UnixMilli())
	}
	if a.Key == slog.LevelKey && len(groups) == 0 {
		lvl := a.Value.Any().(slog.Level)
		lvlStr := lvl.String()
		switch lvl {
		case slog.LevelDebug:
			lvlStr = "D"
		case slog.LevelInfo:
			lvlStr = "I"
		case slog.LevelWarn:
			lvlStr = "W"
		case slog.LevelError:
			lvlStr = "E"
		}
		return slog.String("lvl", lvlStr)
	}
	return a
}
func New() *slog.Logger {
	logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ReplaceAttr: replaceLogAttrs}))
	return logger
}
func InjectHttp(l *slog.Logger, next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		next.ServeHTTP(w, ToReq(r, l))
	})
}