logger_121.go

 1//go:build go1.21
 2// +build go1.21
 3
 4package log
 5
 6import (
 7	"context"
 8	"log/slog"
 9	"runtime"
10	"sync/atomic"
11)
12
13// type aliases for slog.
14type (
15	slogAttr      = slog.Attr
16	slogValue     = slog.Value
17	slogLogValuer = slog.LogValuer
18)
19
20const slogKindGroup = slog.KindGroup
21
22// Enabled reports whether the logger is enabled for the given level.
23//
24// Implements slog.Handler.
25func (l *Logger) Enabled(_ context.Context, level slog.Level) bool {
26	return atomic.LoadInt64(&l.level) <= int64(level)
27}
28
29// Handle handles the Record. It will only be called if Enabled returns true.
30//
31// Implements slog.Handler.
32func (l *Logger) Handle(ctx context.Context, record slog.Record) error {
33	if !l.Enabled(ctx, record.Level) {
34		return nil
35	}
36
37	fields := make([]interface{}, 0, record.NumAttrs()*2)
38	record.Attrs(func(a slog.Attr) bool {
39		fields = append(fields, a.Key, a.Value)
40		return true
41	})
42	// Get the caller frame using the record's PC.
43	frames := runtime.CallersFrames([]uintptr{record.PC})
44	frame, _ := frames.Next()
45	l.handle(Level(record.Level), l.timeFunc(record.Time), []runtime.Frame{frame}, record.Message, fields...)
46	return nil
47}
48
49// WithAttrs returns a new Handler with the given attributes added.
50//
51// Implements slog.Handler.
52func (l *Logger) WithAttrs(attrs []slog.Attr) slog.Handler {
53	fields := make([]interface{}, 0, len(attrs)*2)
54	for _, attr := range attrs {
55		fields = append(fields, attr.Key, attr.Value)
56	}
57	return l.With(fields...)
58}
59
60// WithGroup returns a new Handler with the given group name prepended to the
61// current group name or prefix.
62//
63// Implements slog.Handler.
64func (l *Logger) WithGroup(name string) slog.Handler {
65	if l.prefix != "" {
66		name = l.prefix + "." + name
67	}
68	return l.WithPrefix(name)
69}
70
71var _ slog.Handler = (*Logger)(nil)