1package log
2
3import (
4 "context"
5 "log/slog"
6 "os"
7)
8
9// NewHandler sets up a new slog.Handler with the service name
10// as an attribute
11func NewHandler(name string) slog.Handler {
12 handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
13 Level: slog.LevelDebug,
14 })
15
16 var attrs []slog.Attr
17 attrs = append(attrs, slog.Attr{Key: "service", Value: slog.StringValue(name)})
18 handler.WithAttrs(attrs)
19 return handler
20}
21
22func New(name string) *slog.Logger {
23 return slog.New(NewHandler(name))
24}
25
26func NewContext(ctx context.Context, name string) context.Context {
27 return IntoContext(ctx, New(name))
28}
29
30type ctxKey struct{}
31
32// IntoContext adds a logger to a context. Use FromContext to
33// pull the logger out.
34func IntoContext(ctx context.Context, l *slog.Logger) context.Context {
35 return context.WithValue(ctx, ctxKey{}, l)
36}
37
38// FromContext returns a logger from a context.Context;
39// if the passed context is nil, we return the default slog
40// logger.
41func FromContext(ctx context.Context) *slog.Logger {
42 if ctx != nil {
43 v := ctx.Value(ctxKey{})
44 if v == nil {
45 return slog.Default()
46 }
47 return v.(*slog.Logger)
48 }
49
50 return slog.Default()
51}