-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog.go
More file actions
96 lines (81 loc) · 2.46 KB
/
log.go
File metadata and controls
96 lines (81 loc) · 2.46 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
package initd
import (
"context"
"log/slog"
)
type componentKey struct{}
// withComponent returns a copy of ctx carrying the component name.
// Log records emitted with [slog.InfoContext](ctx, ...) will automatically
// include a "component" attribute.
func withComponent(ctx context.Context, name string) context.Context {
return context.WithValue(ctx, componentKey{}, name)
}
type componentHandler struct {
inner slog.Handler
hasComponent bool
}
func (h *componentHandler) Enabled(ctx context.Context, level slog.Level) bool {
return h.inner.Enabled(ctx, level)
}
func (h *componentHandler) Handle(ctx context.Context, r slog.Record) error {
if !h.hasComponent {
if name, ok := ctx.Value(componentKey{}).(string); ok {
r.AddAttrs(slog.String("component", name))
}
}
return h.inner.Handle(ctx, r)
}
func (h *componentHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
has := h.hasComponent
for _, a := range attrs {
if a.Key == "component" {
has = true
break
}
}
return &componentHandler{inner: h.inner.WithAttrs(attrs), hasComponent: has}
}
func (h *componentHandler) WithGroup(name string) slog.Handler {
return &componentHandler{inner: h.inner.WithGroup(name), hasComponent: h.hasComponent}
}
type durationHandler struct {
inner slog.Handler
}
func (h *durationHandler) Enabled(ctx context.Context, level slog.Level) bool {
return h.inner.Enabled(ctx, level)
}
func (h *durationHandler) Handle(ctx context.Context, r slog.Record) error {
var attrs []slog.Attr
r.Attrs(func(a slog.Attr) bool {
attrs = append(attrs, convertDurationAttr(a))
return true
})
nr := slog.NewRecord(r.Time, r.Level, r.Message, r.PC)
nr.AddAttrs(attrs...)
return h.inner.Handle(ctx, nr)
}
func (h *durationHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
converted := make([]slog.Attr, len(attrs))
for i, a := range attrs {
converted[i] = convertDurationAttr(a)
}
return &durationHandler{inner: h.inner.WithAttrs(converted)}
}
func (h *durationHandler) WithGroup(name string) slog.Handler {
return &durationHandler{inner: h.inner.WithGroup(name)}
}
func convertDurationAttr(a slog.Attr) slog.Attr {
switch a.Value.Kind() {
case slog.KindDuration:
return slog.String(a.Key, a.Value.Duration().String())
case slog.KindGroup:
ga := a.Value.Group()
converted := make([]slog.Attr, len(ga))
for i, g := range ga {
converted[i] = convertDurationAttr(g)
}
return slog.Attr{Key: a.Key, Value: slog.GroupValue(converted...)}
default:
return a
}
}