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