Skip to content

Commit 3746e55

Browse files
committed
slog: JSONHandler
Add a Handler that produces JSON output. Change-Id: Ifbadfb3bea1afbd987a1c48319c0494ebf629d46 Reviewed-on: https://go-review.googlesource.com/c/exp/+/429835 Reviewed-by: Alan Donovan <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]>
1 parent 4397029 commit 3746e55

File tree

6 files changed

+670
-15
lines changed

6 files changed

+670
-15
lines changed

slog/handler.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ func (h *commonHandler) handle(r Record) error {
143143
val := r.Time().Round(0) // strip monotonic to match Attr behavior
144144
if rep == nil {
145145
app.appendKey(key)
146-
app.appendTime(val)
146+
if err := app.appendTime(val); err != nil {
147+
return err
148+
}
147149
} else {
148150
replace(Time(key, val))
149151
}
@@ -226,13 +228,15 @@ func appendAttr(app appender, a Attr) {
226228

227229
// An appender appends keys and values to a buffer.
228230
// TextHandler and JSONHandler both implement it.
231+
// It factors out the format-specific parts of the job.
232+
// Other than growing the buffer, none of the methods should allocate.
229233
type appender interface {
230234
appendStart() // start a sequence of Attrs
231235
appendEnd() // end a sequence of Attrs
232236
appendSep() // separate one Attr from the next
233237
appendKey(key string) // append a key
234238
appendString(string) // append a string that may need to be escaped
235-
appendTime(time.Time) // append a time
239+
appendTime(time.Time) error // append a time
236240
appendSource(file string, line int) // append file:line
237241
appendAttrValue(a Attr) error // append the Attr's value (but not its key)
238242
}

slog/handler_test.go

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,16 @@ type memAppender struct {
105105

106106
func (a *memAppender) set(v any) { a.m[a.key] = v }
107107

108-
func (a *memAppender) appendStart() {}
109-
func (a *memAppender) appendSep() {}
110-
func (a *memAppender) appendEnd() {}
111-
func (a *memAppender) appendKey(key string) { a.key = key }
112-
func (a *memAppender) appendString(s string) { a.set(s) }
113-
func (a *memAppender) appendTime(t time.Time) { a.set(t) }
108+
func (a *memAppender) appendStart() {}
109+
func (a *memAppender) appendSep() {}
110+
func (a *memAppender) appendEnd() {}
111+
func (a *memAppender) appendKey(key string) { a.key = key }
112+
func (a *memAppender) appendString(s string) { a.set(s) }
113+
114+
func (a *memAppender) appendTime(t time.Time) error {
115+
a.set(t)
116+
return nil
117+
}
114118

115119
func (a *memAppender) appendSource(file string, line int) {
116120
a.set(fmt.Sprintf("%s:%d", file, line))
@@ -121,6 +125,24 @@ func (a *memAppender) appendAttrValue(at Attr) error {
121125
return nil
122126
}
123127

128+
const rfc3339Millis = "2006-01-02T15:04:05.000Z07:00"
129+
130+
func TestAppendTimeRFC3339(t *testing.T) {
131+
for _, tm := range []time.Time{
132+
time.Date(2000, 1, 2, 3, 4, 5, 0, time.UTC),
133+
time.Date(2000, 1, 2, 3, 4, 5, 400, time.Local),
134+
time.Date(2000, 11, 12, 3, 4, 500, 5e7, time.UTC),
135+
} {
136+
want := tm.Format(rfc3339Millis)
137+
var buf []byte
138+
buf = appendTimeRFC3339Millis(buf, tm)
139+
got := string(buf)
140+
if got != want {
141+
t.Errorf("got %s, want %s", got, want)
142+
}
143+
}
144+
}
145+
124146
func BenchmarkAppendTime(b *testing.B) {
125147
buf := make([]byte, 0, 100)
126148
tm := time.Date(2022, 3, 4, 5, 6, 7, 823456789, time.Local)

slog/internal/buffer/buffer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ func (b *Buffer) Free() {
3232
bufPool.Put(b)
3333
}
3434
}
35-
func (b *Buffer) Write(p []byte) {
35+
func (b *Buffer) Write(p []byte) (int, error) {
3636
*b = append(*b, p...)
37+
return len(p), nil
3738
}
3839

3940
func (b *Buffer) WriteString(s string) {

0 commit comments

Comments
 (0)