log: simplify fix for datarace when rotating files

This commit is contained in:
Martin Holst Swende 2019-06-13 19:34:38 +02:00
parent 7e30ab3e6b
commit ec192798b8
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -158,17 +158,10 @@ func RotatingFileHandler(path string, limit uint, formatter Format) (Handler, er
if counter == nil { if counter == nil {
counter = new(countingWriter) counter = new(countingWriter)
} }
h := FuncHandler(func(r *Record) error { h := StreamHandler(counter, formatter)
_, err := counter.Write(formatter.Format(r))
return err
})
return FuncHandler(func(r *Record) error { return FuncHandler(func(r *Record) error {
// lazy evaluate, this needs no lock.
lazyEvaluateRecord(r)
counter.Lock() counter.Lock()
defer counter.Unlock()
if counter.count > limit { if counter.count > limit {
counter.Close() counter.Close()
counter.w = nil counter.w = nil
@ -180,11 +173,13 @@ func RotatingFileHandler(path string, limit uint, formatter Format) (Handler, er
0600, 0600,
) )
if err != nil { if err != nil {
counter.Unlock()
return err return err
} }
counter.w = f counter.w = f
counter.count = 0 counter.count = 0
} }
counter.Unlock()
return h.Log(r) return h.Log(r)
}), nil }), nil
} }
@ -392,33 +387,31 @@ func BufferedHandler(bufSize int, h Handler) Handler {
// it if you write your own Handler. // it if you write your own Handler.
func LazyHandler(h Handler) Handler { func LazyHandler(h Handler) Handler {
return FuncHandler(func(r *Record) error { return FuncHandler(func(r *Record) error {
lazyEvaluateRecord(r) // go through the values (odd indices) and reassign
return h.Log(r) // the values of any lazy fn to the result of its execution
}) hadErr := false
} for i := 1; i < len(r.Ctx); i += 2 {
lz, ok := r.Ctx[i].(Lazy)
func lazyEvaluateRecord(r *Record) { if ok {
// go through the values (odd indices) and reassign v, err := evaluateLazy(lz)
// the values of any lazy fn to the result of its execution if err != nil {
hadErr := false hadErr = true
for i := 1; i < len(r.Ctx); i += 2 { r.Ctx[i] = err
if lz, ok := r.Ctx[i].(Lazy); ok { } else {
v, err := evaluateLazy(lz) if cs, ok := v.(stack.CallStack); ok {
if err != nil { v = cs.TrimBelow(r.Call).TrimRuntime()
hadErr = true }
r.Ctx[i] = err r.Ctx[i] = v
} else {
if cs, ok := v.(stack.CallStack); ok {
v = cs.TrimBelow(r.Call).TrimRuntime()
} }
r.Ctx[i] = v
} }
} }
}
if hadErr { if hadErr {
r.Ctx = append(r.Ctx, errorKey, "bad lazy") r.Ctx = append(r.Ctx, errorKey, "bad lazy")
} }
return h.Log(r)
})
} }
func evaluateLazy(lz Lazy) (interface{}, error) { func evaluateLazy(lz Lazy) (interface{}, error) {