114 lines
2.6 KiB
Go
114 lines
2.6 KiB
Go
// Package log is a context wrapper around slog.Logger
|
|
package log
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
stdlog "log"
|
|
"os"
|
|
"runtime/debug"
|
|
"testing"
|
|
|
|
"cdr.dev/slog"
|
|
"cdr.dev/slog/sloggers/sloghuman"
|
|
"cdr.dev/slog/sloggers/slogtest"
|
|
|
|
"oss.terrastruct.com/d2/lib/env"
|
|
)
|
|
|
|
var _default = slog.Make(sloghuman.Sink(os.Stderr)).Named("default")
|
|
|
|
func Init() {
|
|
stdlib := slog.Stdlib(context.Background(), _default, slog.LevelInfo)
|
|
log.SetOutput(stdlib.Writer())
|
|
}
|
|
|
|
type loggerKey struct{}
|
|
|
|
func from(ctx context.Context) slog.Logger {
|
|
l, ok := ctx.Value(loggerKey{}).(slog.Logger)
|
|
if !ok {
|
|
_default.Warn(ctx, "missing slog.Logger in context, see lib/log.With", slog.F("stack", string(debug.Stack())))
|
|
return _default
|
|
}
|
|
return l
|
|
}
|
|
|
|
func With(ctx context.Context, l slog.Logger) context.Context {
|
|
return context.WithValue(ctx, loggerKey{}, l)
|
|
}
|
|
|
|
// WithTB calls With with the result of slogtest.Make.
|
|
func WithTB(ctx context.Context, t testing.TB, opts *slogtest.Options) context.Context {
|
|
l := slogtest.Make(t, opts)
|
|
if env.Debug() {
|
|
l = l.Leveled(slog.LevelDebug)
|
|
}
|
|
return With(ctx, l)
|
|
}
|
|
|
|
func Debug(ctx context.Context, msg string, fields ...slog.Field) {
|
|
slog.Helper()
|
|
from(ctx).Debug(ctx, msg, fields...)
|
|
}
|
|
|
|
func Info(ctx context.Context, msg string, fields ...slog.Field) {
|
|
slog.Helper()
|
|
from(ctx).Info(ctx, msg, fields...)
|
|
}
|
|
|
|
func Warn(ctx context.Context, msg string, fields ...slog.Field) {
|
|
slog.Helper()
|
|
from(ctx).Warn(ctx, msg, fields...)
|
|
}
|
|
|
|
func Error(ctx context.Context, msg string, fields ...slog.Field) {
|
|
slog.Helper()
|
|
from(ctx).Error(ctx, msg, fields...)
|
|
}
|
|
|
|
func Critical(ctx context.Context, msg string, fields ...slog.Field) {
|
|
slog.Helper()
|
|
from(ctx).Critical(ctx, msg, fields...)
|
|
}
|
|
|
|
func Fatal(ctx context.Context, msg string, fields ...slog.Field) {
|
|
slog.Helper()
|
|
from(ctx).Fatal(ctx, msg, fields...)
|
|
}
|
|
|
|
func Named(ctx context.Context, name string) context.Context {
|
|
return With(ctx, from(ctx).Named(name))
|
|
}
|
|
|
|
func Leveled(ctx context.Context, level slog.Level) context.Context {
|
|
return With(ctx, from(ctx).Leveled(level))
|
|
}
|
|
|
|
func AppendSinks(ctx context.Context, s ...slog.Sink) context.Context {
|
|
return With(ctx, from(ctx).AppendSinks(s...))
|
|
}
|
|
|
|
func Sync(ctx context.Context) {
|
|
from(ctx).Sync()
|
|
}
|
|
|
|
func Stdlib(ctx context.Context, level slog.Level) *log.Logger {
|
|
return slog.Stdlib(ctx, from(ctx), level)
|
|
}
|
|
|
|
func Fork(ctx, loggerCtx context.Context) context.Context {
|
|
return With(ctx, from(loggerCtx))
|
|
}
|
|
|
|
func Stderr(ctx context.Context) context.Context {
|
|
l := slog.Make(sloghuman.Sink(os.Stderr))
|
|
if os.Getenv("DEBUG") == "1" {
|
|
l = l.Leveled(slog.LevelDebug)
|
|
}
|
|
|
|
sl := slog.Stdlib(ctx, l, slog.LevelInfo)
|
|
stdlog.SetOutput(sl.Writer())
|
|
|
|
return With(ctx, l)
|
|
}
|