Source file
src/log/slog/logger.go
1
2
3
4
5 package slog
6
7 import (
8 "context"
9 "log"
10 loginternal "log/internal"
11 "log/slog/internal"
12 "runtime"
13 "sync/atomic"
14 "time"
15 )
16
17 var defaultLogger atomic.Pointer[Logger]
18
19 var logLoggerLevel LevelVar
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 func SetLogLoggerLevel(level Level) (oldLevel Level) {
44 oldLevel = logLoggerLevel.Level()
45 logLoggerLevel.Set(level)
46 return
47 }
48
49 func init() {
50 defaultLogger.Store(New(newDefaultHandler(loginternal.DefaultOutput)))
51 }
52
53
54 func Default() *Logger { return defaultLogger.Load() }
55
56
57
58
59
60
61 func SetDefault(l *Logger) {
62 defaultLogger.Store(l)
63
64
65
66
67
68
69 if _, ok := l.Handler().(*defaultHandler); !ok {
70 capturePC := log.Flags()&(log.Lshortfile|log.Llongfile) != 0
71 log.SetOutput(&handlerWriter{l.Handler(), &logLoggerLevel, capturePC})
72 log.SetFlags(0)
73 }
74 }
75
76
77
78 type handlerWriter struct {
79 h Handler
80 level Leveler
81 capturePC bool
82 }
83
84 func (w *handlerWriter) Write(buf []byte) (int, error) {
85 level := w.level.Level()
86 if !w.h.Enabled(context.Background(), level) {
87 return 0, nil
88 }
89 var pc uintptr
90 if !internal.IgnorePC && w.capturePC {
91
92 var pcs [1]uintptr
93 runtime.Callers(4, pcs[:])
94 pc = pcs[0]
95 }
96
97
98 origLen := len(buf)
99 if len(buf) > 0 && buf[len(buf)-1] == '\n' {
100 buf = buf[:len(buf)-1]
101 }
102 r := NewRecord(time.Now(), level, string(buf), pc)
103 return origLen, w.h.Handle(context.Background(), r)
104 }
105
106
107
108
109
110
111
112 type Logger struct {
113 handler Handler
114 }
115
116 func (l *Logger) clone() *Logger {
117 c := *l
118 return &c
119 }
120
121
122 func (l *Logger) Handler() Handler { return l.handler }
123
124
125
126
127 func (l *Logger) With(args ...any) *Logger {
128 if len(args) == 0 {
129 return l
130 }
131 c := l.clone()
132 c.handler = l.handler.WithAttrs(argsToAttrSlice(args))
133 return c
134 }
135
136
137
138
139
140
141
142 func (l *Logger) WithGroup(name string) *Logger {
143 if name == "" {
144 return l
145 }
146 c := l.clone()
147 c.handler = l.handler.WithGroup(name)
148 return c
149 }
150
151
152 func New(h Handler) *Logger {
153 if h == nil {
154 panic("nil Handler")
155 }
156 return &Logger{handler: h}
157 }
158
159
160 func With(args ...any) *Logger {
161 return Default().With(args...)
162 }
163
164
165 func (l *Logger) Enabled(ctx context.Context, level Level) bool {
166 if ctx == nil {
167 ctx = context.Background()
168 }
169 return l.Handler().Enabled(ctx, level)
170 }
171
172
173
174
175 func NewLogLogger(h Handler, level Level) *log.Logger {
176 return log.New(&handlerWriter{h, level, true}, "", 0)
177 }
178
179
180
181
182
183
184
185
186
187
188
189 func (l *Logger) Log(ctx context.Context, level Level, msg string, args ...any) {
190 l.log(ctx, level, msg, args...)
191 }
192
193
194 func (l *Logger) LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
195 l.logAttrs(ctx, level, msg, attrs...)
196 }
197
198
199 func (l *Logger) Debug(msg string, args ...any) {
200 l.log(context.Background(), LevelDebug, msg, args...)
201 }
202
203
204 func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any) {
205 l.log(ctx, LevelDebug, msg, args...)
206 }
207
208
209 func (l *Logger) Info(msg string, args ...any) {
210 l.log(context.Background(), LevelInfo, msg, args...)
211 }
212
213
214 func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any) {
215 l.log(ctx, LevelInfo, msg, args...)
216 }
217
218
219 func (l *Logger) Warn(msg string, args ...any) {
220 l.log(context.Background(), LevelWarn, msg, args...)
221 }
222
223
224 func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any) {
225 l.log(ctx, LevelWarn, msg, args...)
226 }
227
228
229 func (l *Logger) Error(msg string, args ...any) {
230 l.log(context.Background(), LevelError, msg, args...)
231 }
232
233
234 func (l *Logger) ErrorContext(ctx context.Context, msg string, args ...any) {
235 l.log(ctx, LevelError, msg, args...)
236 }
237
238
239
240
241 func (l *Logger) log(ctx context.Context, level Level, msg string, args ...any) {
242 if !l.Enabled(ctx, level) {
243 return
244 }
245 var pc uintptr
246 if !internal.IgnorePC {
247 var pcs [1]uintptr
248
249 runtime.Callers(3, pcs[:])
250 pc = pcs[0]
251 }
252 r := NewRecord(time.Now(), level, msg, pc)
253 r.Add(args...)
254 if ctx == nil {
255 ctx = context.Background()
256 }
257 _ = l.Handler().Handle(ctx, r)
258 }
259
260
261 func (l *Logger) logAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
262 if !l.Enabled(ctx, level) {
263 return
264 }
265 var pc uintptr
266 if !internal.IgnorePC {
267 var pcs [1]uintptr
268
269 runtime.Callers(3, pcs[:])
270 pc = pcs[0]
271 }
272 r := NewRecord(time.Now(), level, msg, pc)
273 r.AddAttrs(attrs...)
274 if ctx == nil {
275 ctx = context.Background()
276 }
277 _ = l.Handler().Handle(ctx, r)
278 }
279
280
281 func Debug(msg string, args ...any) {
282 Default().log(context.Background(), LevelDebug, msg, args...)
283 }
284
285
286 func DebugContext(ctx context.Context, msg string, args ...any) {
287 Default().log(ctx, LevelDebug, msg, args...)
288 }
289
290
291 func Info(msg string, args ...any) {
292 Default().log(context.Background(), LevelInfo, msg, args...)
293 }
294
295
296 func InfoContext(ctx context.Context, msg string, args ...any) {
297 Default().log(ctx, LevelInfo, msg, args...)
298 }
299
300
301 func Warn(msg string, args ...any) {
302 Default().log(context.Background(), LevelWarn, msg, args...)
303 }
304
305
306 func WarnContext(ctx context.Context, msg string, args ...any) {
307 Default().log(ctx, LevelWarn, msg, args...)
308 }
309
310
311 func Error(msg string, args ...any) {
312 Default().log(context.Background(), LevelError, msg, args...)
313 }
314
315
316 func ErrorContext(ctx context.Context, msg string, args ...any) {
317 Default().log(ctx, LevelError, msg, args...)
318 }
319
320
321 func Log(ctx context.Context, level Level, msg string, args ...any) {
322 Default().log(ctx, level, msg, args...)
323 }
324
325
326 func LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
327 Default().logAttrs(ctx, level, msg, attrs...)
328 }
329
View as plain text