Files
byre/internal/jsonlines/jsonlines.go
T

56 lines
1.1 KiB
Go
Raw Normal View History

2026-10-23 16:31:34 -07:00
package jsonlines
import (
"bufio"
"bytes"
"io"
"log/slog"
"sync/atomic"
"time"
)
type Stream struct {
vendor string
onBad func(line []byte, reason string)
lastLine atomic.Int64
}
func New(vendor string, onBad func(line []byte, reason string)) *Stream {
s := &Stream{vendor: vendor, onBad: onBad}
s.lastLine.Store(time.Now().UnixNano())
return s
}
func (s *Stream) LastLine() time.Time {
return time.Unix(0, s.lastLine.Load())
}
func (s *Stream) BadLine(line []byte, reason string) {
slog.Warn("bad "+s.vendor+" line", "reason", reason, "line", string(line))
if s.onBad != nil {
s.onBad(line, reason)
}
}
func (s *Stream) Read(stdout io.Reader, handle func(line []byte)) {
r := bufio.NewReader(stdout)
for {
line, err := r.ReadBytes('\n')
line = bytes.TrimRight(line, "\r\n")
if len(line) > 0 {
s.lastLine.Store(time.Now().UnixNano())
if line[0] == '{' {
handle(line)
} else {
s.BadLine(line, "not a JSON object")
}
}
if err != nil {
if err != io.EOF {
slog.Error("read "+s.vendor+" stdout", "err", err)
}
return
}
}
}