From ec192798b88cf30f406ffe70ce36c58ebdd093a6 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 13 Jun 2019 19:34:38 +0200 Subject: [PATCH] log: simplify fix for datarace when rotating files --- log/handler.go | 55 ++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/log/handler.go b/log/handler.go index 085d387ad7..e7c65b51cd 100644 --- a/log/handler.go +++ b/log/handler.go @@ -158,17 +158,10 @@ func RotatingFileHandler(path string, limit uint, formatter Format) (Handler, er if counter == nil { counter = new(countingWriter) } - h := FuncHandler(func(r *Record) error { - _, err := counter.Write(formatter.Format(r)) - return err - }) + h := StreamHandler(counter, formatter) return FuncHandler(func(r *Record) error { - // lazy evaluate, this needs no lock. - lazyEvaluateRecord(r) - counter.Lock() - defer counter.Unlock() if counter.count > limit { counter.Close() counter.w = nil @@ -180,11 +173,13 @@ func RotatingFileHandler(path string, limit uint, formatter Format) (Handler, er 0600, ) if err != nil { + counter.Unlock() return err } counter.w = f counter.count = 0 } + counter.Unlock() return h.Log(r) }), nil } @@ -392,33 +387,31 @@ func BufferedHandler(bufSize int, h Handler) Handler { // it if you write your own Handler. func LazyHandler(h Handler) Handler { return FuncHandler(func(r *Record) error { - lazyEvaluateRecord(r) - return h.Log(r) - }) -} - -func lazyEvaluateRecord(r *Record) { - // go through the values (odd indices) and reassign - // the values of any lazy fn to the result of its execution - hadErr := false - for i := 1; i < len(r.Ctx); i += 2 { - if lz, ok := r.Ctx[i].(Lazy); ok { - v, err := evaluateLazy(lz) - if err != nil { - hadErr = true - r.Ctx[i] = err - } else { - if cs, ok := v.(stack.CallStack); ok { - v = cs.TrimBelow(r.Call).TrimRuntime() + // go through the values (odd indices) and reassign + // 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) + if ok { + v, err := evaluateLazy(lz) + if err != nil { + hadErr = true + r.Ctx[i] = err + } else { + if cs, ok := v.(stack.CallStack); ok { + v = cs.TrimBelow(r.Call).TrimRuntime() + } + r.Ctx[i] = v } - r.Ctx[i] = v } } - } - if hadErr { - r.Ctx = append(r.Ctx, errorKey, "bad lazy") - } + if hadErr { + r.Ctx = append(r.Ctx, errorKey, "bad lazy") + } + + return h.Log(r) + }) } func evaluateLazy(lz Lazy) (interface{}, error) {