-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger.go
102 lines (81 loc) · 2.54 KB
/
logger.go
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
package sloghighlight
import (
"context"
"fmt"
"log/slog"
"runtime"
"slices"
"github.com/highlight/highlight/sdk/highlight-go"
hlog "github.com/highlight/highlight/sdk/highlight-go/log"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)
type HighlightHandler struct {
level slog.Leveler
attrs []slog.Attr
groups []string
}
var _ slog.Handler = (*HighlightHandler)(nil)
// NewHighlightHandler creates a new HighlightHandler.
// Default level is LevelInfo.
func NewHighlightHandler(options ...HighlightHandlerOption) slog.Handler {
h := &HighlightHandler{
level: slog.LevelInfo,
}
for _, option := range options {
option(h)
}
return h
}
// Enabled returns true if the level is enabled.
func (h *HighlightHandler) Enabled(_ context.Context, level slog.Level) bool {
return h.level.Level() <= level.Level()
}
// Handle handles the record.
func (h *HighlightHandler) Handle(ctx context.Context, r slog.Record) error {
span, _ := highlight.StartTrace(ctx, "highlight-go/log")
defer highlight.EndTrace(span)
// add default attributes
attrs := []attribute.KeyValue{
hlog.LogSeverityKey.String(r.Level.String()),
hlog.LogMessageKey.String(r.Message),
}
// if PC is not nil, get caller function info
if r.PC != 0 {
fs := runtime.CallersFrames([]uintptr{r.PC})
f, _ := fs.Next()
source := attribute.Key("source").String(fmt.Sprintf("%s:%d (%s)", f.File, f.Line, f.Function))
attrs = append(attrs, source)
}
r.Attrs(func(attr slog.Attr) bool {
key := attribute.Key(attr.Key)
// TODO: correctly type infer the values
attrs = append(attrs, key.String(fmt.Sprintf("%v", attr.Value)))
return true
})
attrs = append(attrs, attribute.Key("groups").StringSlice(h.groups))
span.AddEvent(highlight.LogEvent, trace.WithAttributes(attrs...), trace.WithTimestamp(r.Time))
if r.Level <= slog.LevelError {
span.SetStatus(codes.Error, r.Message)
}
return nil
}
// WithLevel returns a new HighlightHandler with the attributes added.
func (h *HighlightHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
newAttrs := append(slices.Clone[[]slog.Attr](attrs), h.attrs...)
return &HighlightHandler{
level: h.level,
attrs: newAttrs,
groups: slices.Clone[[]string](h.groups),
}
}
// WithGroup returns a new HighlightHandler with the group added.
func (h *HighlightHandler) WithGroup(name string) slog.Handler {
newGroups := append(slices.Clone[[]string](h.groups), name)
return &HighlightHandler{
level: h.level,
attrs: slices.Clone[[]slog.Attr](h.attrs),
groups: newGroups,
}
}