...
1
2
3
4
19
20 package logr
21
22 import (
23 "context"
24 "log/slog"
25 "runtime"
26 "time"
27 )
28
29 var (
30 _ LogSink = &slogSink{}
31 _ CallDepthLogSink = &slogSink{}
32 _ Underlier = &slogSink{}
33 )
34
35
36 type Underlier interface {
37
38 GetUnderlying() slog.Handler
39 }
40
41 const (
42
43 nameKey = "logger"
44
45
46 errKey = "err"
47 )
48
49 type slogSink struct {
50 callDepth int
51 name string
52 handler slog.Handler
53 }
54
55 func (l *slogSink) Init(info RuntimeInfo) {
56 l.callDepth = info.CallDepth
57 }
58
59 func (l *slogSink) GetUnderlying() slog.Handler {
60 return l.handler
61 }
62
63 func (l *slogSink) WithCallDepth(depth int) LogSink {
64 newLogger := *l
65 newLogger.callDepth += depth
66 return &newLogger
67 }
68
69 func (l *slogSink) Enabled(level int) bool {
70 return l.handler.Enabled(context.Background(), slog.Level(-level))
71 }
72
73 func (l *slogSink) Info(level int, msg string, kvList ...interface{}) {
74 l.log(nil, msg, slog.Level(-level), kvList...)
75 }
76
77 func (l *slogSink) Error(err error, msg string, kvList ...interface{}) {
78 l.log(err, msg, slog.LevelError, kvList...)
79 }
80
81 func (l *slogSink) log(err error, msg string, level slog.Level, kvList ...interface{}) {
82 var pcs [1]uintptr
83
84 runtime.Callers(3+l.callDepth, pcs[:])
85
86 record := slog.NewRecord(time.Now(), level, msg, pcs[0])
87 if l.name != "" {
88 record.AddAttrs(slog.String(nameKey, l.name))
89 }
90 if err != nil {
91 record.AddAttrs(slog.Any(errKey, err))
92 }
93 record.Add(kvList...)
94 _ = l.handler.Handle(context.Background(), record)
95 }
96
97 func (l slogSink) WithName(name string) LogSink {
98 if l.name != "" {
99 l.name += "/"
100 }
101 l.name += name
102 return &l
103 }
104
105 func (l slogSink) WithValues(kvList ...interface{}) LogSink {
106 l.handler = l.handler.WithAttrs(kvListToAttrs(kvList...))
107 return &l
108 }
109
110 func kvListToAttrs(kvList ...interface{}) []slog.Attr {
111
112 record := slog.NewRecord(time.Time{}, 0, "", 0)
113 record.Add(kvList...)
114 attrs := make([]slog.Attr, 0, record.NumAttrs())
115 record.Attrs(func(attr slog.Attr) bool {
116 attrs = append(attrs, attr)
117 return true
118 })
119 return attrs
120 }
121
View as plain text