don't create a trace file here, write trace to io.Writer

Arguably, it's not a library's responsibility to create a trace file,
and to decide on the compression algorithm. The design is cleaner if we
just dump the trace to an io.WriteCloser, and let the application decide
how to handle the concrete implementation.
This commit is contained in:
Marten Seemann 2022-06-07 11:44:34 +02:00
parent 89b666f703
commit f4b09ff457

View File

@ -1,11 +1,9 @@
package rcmgr package rcmgr
import ( import (
"compress/gzip"
"context" "context"
"encoding/json" "encoding/json"
"io" "io"
"os"
"sync" "sync"
"time" "time"
@ -13,7 +11,7 @@ import (
) )
type trace struct { type trace struct {
path string out io.WriteCloser
ctx context.Context ctx context.Context
cancel func() cancel func()
@ -24,9 +22,9 @@ type trace struct {
pend []interface{} pend []interface{}
} }
func WithTrace(path string) Option { func WithTrace(out io.WriteCloser) Option {
return func(r *resourceManager) error { return func(r *resourceManager) error {
r.trace = &trace{path: path} r.trace = &trace{out: out}
return nil return nil
} }
} }
@ -83,14 +81,11 @@ func (t *trace) push(evt TraceEvt) {
t.pend = append(t.pend, evt) t.pend = append(t.pend, evt)
} }
func (t *trace) background(out io.WriteCloser) { func (t *trace) background() {
defer close(t.closed) defer close(t.closed)
defer out.Close() defer t.out.Close()
gzOut := gzip.NewWriter(out) jsonOut := json.NewEncoder(t.out)
defer gzOut.Close()
jsonOut := json.NewEncoder(gzOut)
ticker := time.NewTicker(time.Second) ticker := time.NewTicker(time.Second)
defer ticker.Stop() defer ticker.Stop()
@ -121,15 +116,6 @@ func (t *trace) background(out io.WriteCloser) {
t.mx.Unlock() t.mx.Unlock()
return return
} }
if err := gzOut.Flush(); err != nil {
log.Warnf("error flushing rcmgr trace: %s", err)
t.mx.Lock()
t.done = true
t.mx.Unlock()
return
}
case <-t.ctx.Done(): case <-t.ctx.Done():
getEvents() getEvents()
@ -141,11 +127,6 @@ func (t *trace) background(out io.WriteCloser) {
log.Warnf("error writing rcmgr trace: %s", err) log.Warnf("error writing rcmgr trace: %s", err)
return return
} }
if err := gzOut.Flush(); err != nil {
log.Warnf("error flushing rcmgr trace: %s", err)
}
return return
} }
} }
@ -169,12 +150,7 @@ func (t *trace) Start(limits Limiter) error {
t.ctx, t.cancel = context.WithCancel(context.Background()) t.ctx, t.cancel = context.WithCancel(context.Background())
t.closed = make(chan struct{}) t.closed = make(chan struct{})
out, err := os.OpenFile(t.path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) go t.background()
if err != nil {
return nil
}
go t.background(out)
t.push(TraceEvt{ t.push(TraceEvt{
Type: traceStartEvt, Type: traceStartEvt,