-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathslog.go
More file actions
123 lines (108 loc) · 3.91 KB
/
slog.go
File metadata and controls
123 lines (108 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package sqlslog
import (
"io"
"log/slog"
"os"
)
type slogOptions struct {
slog.HandlerOptions
handler slog.Handler
handlerFunc func(io.Writer, *slog.HandlerOptions) slog.Handler
logWriter io.Writer
}
func defaultSlogOptions() *slogOptions {
return &slogOptions{
handlerFunc: NewTextHandler,
logWriter: os.Stdout,
HandlerOptions: slog.HandlerOptions{},
}
}
// Handler sets the slog.Handler to be used.
// If not set, the default is created by HandlerFunc, Writer, SlogOptions.
// If you set this option, HandlerFunc, Writer, SlogOptions will be ignored.
// WARNING: If given handler is created without ReplaceAttr options,
// LevelTrace and LevelVerbose will be logged as DEBUG-4 and DEBUG-8.
func Handler(handler slog.Handler) Option {
return func(o *options) { o.SlogOptions.handler = handler }
}
// HandlerFunc sets the function to create the slog.Handler.
// If not set, the default is [NewTextHandler].
// WARNING: Unless given handlerFunc considers ReplaceAttr options like [NewJSONHandler] or [NewTextHandler] of sqlslog package,
// LevelTrace and LevelVerbose will be logged as DEBUG-4 and DEBUG-8.
func HandlerFunc(handlerFunc func(io.Writer, *slog.HandlerOptions) slog.Handler) Option {
return func(o *options) { o.SlogOptions.handlerFunc = handlerFunc }
}
// LogWriter sets the writer to be used for the slog.Handler.
// If not set, the default is os.Stdout.
func LogWriter(w io.Writer) Option {
return func(o *options) { o.SlogOptions.logWriter = w }
}
// HandlerOptions sets the options to be used for the slog.Handler.
// If not set, the default is an empty [slog.HandlerOptions].
func HandlerOptions(opts *slog.HandlerOptions) Option {
return func(o *options) {
if opts == nil {
opts = &slog.HandlerOptions{}
}
o.SlogOptions.HandlerOptions = *opts
}
}
// AddSource sets whether to add the source to the log.
func AddSource(v bool) Option {
return func(o *options) { o.SlogOptions.AddSource = v }
}
// LogLevel sets the log level to be used.
func LogLevel(v slog.Leveler) Option {
return func(o *options) { o.SlogOptions.Level = v }
}
// ReplaceAttr sets the function to replace the attributes.
func LogReplaceAttr(f func([]string, slog.Attr) slog.Attr) Option {
return func(o *options) { o.SlogOptions.ReplaceAttr = f }
}
// NewJSONHandler returns a new JSON handler using [slog.NewJSONHandler]
// with custom options for sqlslog.
// See [WrapHandlerOptions] for details on the options.
func NewJSONHandler(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
return slog.NewJSONHandler(w, WrapHandlerOptions(opts))
}
// NewTextHandler returns a new Text handler using [slog.NewTextHandler]
// with custom options for sqlslog.
// See [WrapHandlerOptions] for details on the options.
func NewTextHandler(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
return slog.NewTextHandler(w, WrapHandlerOptions(opts))
}
// WrapHandlerOptions wraps the options with custom options for sqlslog.
// It merges ReplaceAttr functions with [ReplaceLevelAttr].
func WrapHandlerOptions(opts *slog.HandlerOptions) *slog.HandlerOptions {
if opts == nil {
opts = &slog.HandlerOptions{}
}
opts.ReplaceAttr = MergeReplaceAttrs(opts.ReplaceAttr, ReplaceLevelAttr)
return opts
}
// ReplaceLevelAttr is a type of ReplaceAttr for [slog.HandlerOptions].
type ReplaceAttrFunc = func([]string, slog.Attr) slog.Attr
// MergeReplaceAttrs merges multiple [ReplaceAttrFunc] functions.
// If functions are nil or empty, it returns nil.
// If there is only one function, it returns that function.
// If there are multiple functions, it returns a merged function.
func MergeReplaceAttrs(funcs ...ReplaceAttrFunc) ReplaceAttrFunc {
var valids []ReplaceAttrFunc
for _, f := range funcs {
if f != nil {
valids = append(valids, f)
}
}
if len(valids) == 0 {
return nil
}
if len(valids) == 1 {
return valids[0]
}
return func(group []string, a slog.Attr) slog.Attr {
for _, f := range funcs {
a = f(group, a)
}
return a
}
}