...
1
2
3
4
5 package benchmarks
6
7
8
9 import (
10 "context"
11 "fmt"
12 "io"
13 "strconv"
14 "time"
15
16 "golang.org/x/exp/slog"
17 "golang.org/x/exp/slog/internal/buffer"
18 )
19
20
21
22
23
24
25
26
27 type fastTextHandler struct {
28 w io.Writer
29 }
30
31 func newFastTextHandler(w io.Writer) slog.Handler {
32 return &fastTextHandler{w: w}
33 }
34
35 func (h *fastTextHandler) Enabled(context.Context, slog.Level) bool { return true }
36
37 func (h *fastTextHandler) Handle(_ context.Context, r slog.Record) error {
38 buf := buffer.New()
39 defer buf.Free()
40
41 if !r.Time.IsZero() {
42 buf.WriteString("time=")
43 h.appendTime(buf, r.Time)
44 buf.WriteByte(' ')
45 }
46 buf.WriteString("level=")
47 *buf = strconv.AppendInt(*buf, int64(r.Level), 10)
48 buf.WriteByte(' ')
49 buf.WriteString("msg=")
50 buf.WriteString(r.Message)
51 r.Attrs(func(a slog.Attr) bool {
52 buf.WriteByte(' ')
53 buf.WriteString(a.Key)
54 buf.WriteByte('=')
55 h.appendValue(buf, a.Value)
56 return true
57 })
58 buf.WriteByte('\n')
59 _, err := h.w.Write(*buf)
60 return err
61 }
62
63 func (h *fastTextHandler) appendValue(buf *buffer.Buffer, v slog.Value) {
64 switch v.Kind() {
65 case slog.KindString:
66 buf.WriteString(v.String())
67 case slog.KindInt64:
68 *buf = strconv.AppendInt(*buf, v.Int64(), 10)
69 case slog.KindUint64:
70 *buf = strconv.AppendUint(*buf, v.Uint64(), 10)
71 case slog.KindFloat64:
72 *buf = strconv.AppendFloat(*buf, v.Float64(), 'g', -1, 64)
73 case slog.KindBool:
74 *buf = strconv.AppendBool(*buf, v.Bool())
75 case slog.KindDuration:
76 *buf = strconv.AppendInt(*buf, v.Duration().Nanoseconds(), 10)
77 case slog.KindTime:
78 h.appendTime(buf, v.Time())
79 case slog.KindAny:
80 a := v.Any()
81 switch a := a.(type) {
82 case error:
83 buf.WriteString(a.Error())
84 default:
85 buf.WriteString(fmt.Sprint(a))
86 }
87 default:
88 panic(fmt.Sprintf("bad kind: %s", v.Kind()))
89 }
90 }
91
92 func (h *fastTextHandler) appendTime(buf *buffer.Buffer, t time.Time) {
93 *buf = strconv.AppendInt(*buf, t.Unix(), 10)
94 }
95
96 func (h *fastTextHandler) WithAttrs([]slog.Attr) slog.Handler {
97 panic("fastTextHandler: With unimplemented")
98 }
99
100 func (*fastTextHandler) WithGroup(string) slog.Handler {
101 panic("fastTextHandler: WithGroup unimplemented")
102 }
103
104
105
106
107
108
109
110
111 type asyncHandler struct {
112 ringBuffer [100]slog.Record
113 next int
114 }
115
116 func newAsyncHandler() *asyncHandler {
117 return &asyncHandler{}
118 }
119
120 func (*asyncHandler) Enabled(context.Context, slog.Level) bool { return true }
121
122 func (h *asyncHandler) Handle(_ context.Context, r slog.Record) error {
123 h.ringBuffer[h.next] = r.Clone()
124 h.next = (h.next + 1) % len(h.ringBuffer)
125 return nil
126 }
127
128 func (*asyncHandler) WithAttrs([]slog.Attr) slog.Handler {
129 panic("asyncHandler: With unimplemented")
130 }
131
132 func (*asyncHandler) WithGroup(string) slog.Handler {
133 panic("asyncHandler: WithGroup unimplemented")
134 }
135
136 type disabledHandler struct{}
137
138 func (disabledHandler) Enabled(context.Context, slog.Level) bool { return false }
139 func (disabledHandler) Handle(context.Context, slog.Record) error { panic("should not be called") }
140
141 func (disabledHandler) WithAttrs([]slog.Attr) slog.Handler {
142 panic("disabledHandler: With unimplemented")
143 }
144
145 func (disabledHandler) WithGroup(string) slog.Handler {
146 panic("disabledHandler: WithGroup unimplemented")
147 }
148
View as plain text