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