2023-07-02 02:57:36 +00:00
|
|
|
package logger
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"log"
|
2023-10-22 04:51:29 +00:00
|
|
|
"log/slog"
|
2023-07-02 02:57:36 +00:00
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"sync"
|
|
|
|
|
2023-10-22 04:51:29 +00:00
|
|
|
"github.com/ttys3/slogx"
|
2023-07-02 02:57:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var ConfigPrefix = ""
|
|
|
|
|
|
|
|
var rootLogger *slog.Logger
|
|
|
|
var setup sync.Once
|
|
|
|
|
|
|
|
func Setup() *slog.Logger {
|
|
|
|
|
|
|
|
setup.Do(func() {
|
|
|
|
|
|
|
|
var programLevel = new(slog.LevelVar) // Info by default
|
|
|
|
|
|
|
|
envVar := "DEBUG"
|
|
|
|
if len(ConfigPrefix) > 0 {
|
|
|
|
envVar = ConfigPrefix + "_" + envVar
|
|
|
|
}
|
|
|
|
|
|
|
|
if opt := os.Getenv(envVar); len(opt) > 0 {
|
|
|
|
if debug, _ := strconv.ParseBool(opt); debug {
|
|
|
|
programLevel.Set(slog.LevelDebug)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logOptions := &slog.HandlerOptions{Level: programLevel}
|
|
|
|
|
|
|
|
if len(os.Getenv("INVOCATION_ID")) > 0 {
|
|
|
|
// don't add timestamps when running under systemd
|
|
|
|
log.Default().SetFlags(0)
|
|
|
|
|
|
|
|
logReplace := func(groups []string, a slog.Attr) slog.Attr {
|
|
|
|
// Remove time
|
|
|
|
if a.Key == slog.TimeKey && len(groups) == 0 {
|
2023-10-22 04:51:29 +00:00
|
|
|
return slog.Attr{}
|
2023-07-02 02:57:36 +00:00
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
logOptions.ReplaceAttr = logReplace
|
|
|
|
}
|
|
|
|
|
2023-10-22 04:51:29 +00:00
|
|
|
logHandler := slogx.NewTracingHandler(slog.NewTextHandler(os.Stderr, logOptions))
|
2023-07-02 02:57:36 +00:00
|
|
|
|
|
|
|
// https://github.com/cyrusaf/ctxlog/pull/1
|
|
|
|
// log := slog.New(ctxlog.NewHandler(logHandler))
|
|
|
|
log := slog.New(logHandler)
|
|
|
|
|
|
|
|
slog.SetDefault(log)
|
|
|
|
|
|
|
|
rootLogger = log
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
return rootLogger
|
|
|
|
}
|
|
|
|
|
|
|
|
type loggerKey struct{}
|
|
|
|
|
|
|
|
// NewContext adds the logger to the context.
|
|
|
|
func NewContext(ctx context.Context, l *slog.Logger) context.Context {
|
|
|
|
return context.WithValue(ctx, loggerKey{}, l)
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromContext retrieves a logger from the context. If there is none,
|
|
|
|
// it returns the default logger.
|
|
|
|
func FromContext(ctx context.Context) *slog.Logger {
|
|
|
|
if l, ok := ctx.Value(loggerKey{}).(*slog.Logger); ok {
|
|
|
|
return l
|
|
|
|
}
|
|
|
|
return Setup()
|
|
|
|
}
|