mirror of https://github.com/sirupsen/logrus.git
Merge pull request #916 from sirupsen/fix_race_getcaller
Fix race getcaller
This commit is contained in:
commit
d7b6bf5e4d
21
entry.go
21
entry.go
|
@ -156,20 +156,23 @@ func getPackageName(f string) string {
|
||||||
|
|
||||||
// getCaller retrieves the name of the first non-logrus calling function
|
// getCaller retrieves the name of the first non-logrus calling function
|
||||||
func getCaller() *runtime.Frame {
|
func getCaller() *runtime.Frame {
|
||||||
|
|
||||||
|
// cache this package's fully-qualified name
|
||||||
|
callerInitOnce.Do(func() {
|
||||||
|
pcs := make([]uintptr, 2)
|
||||||
|
_ = runtime.Callers(0, pcs)
|
||||||
|
logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name())
|
||||||
|
|
||||||
|
// now that we have the cache, we can skip a minimum count of known-logrus functions
|
||||||
|
// XXX this is dubious, the number of frames may vary
|
||||||
|
minimumCallerDepth = knownLogrusFrames
|
||||||
|
})
|
||||||
|
|
||||||
// Restrict the lookback frames to avoid runaway lookups
|
// Restrict the lookback frames to avoid runaway lookups
|
||||||
pcs := make([]uintptr, maximumCallerDepth)
|
pcs := make([]uintptr, maximumCallerDepth)
|
||||||
depth := runtime.Callers(minimumCallerDepth, pcs)
|
depth := runtime.Callers(minimumCallerDepth, pcs)
|
||||||
frames := runtime.CallersFrames(pcs[:depth])
|
frames := runtime.CallersFrames(pcs[:depth])
|
||||||
|
|
||||||
// cache this package's fully-qualified name
|
|
||||||
callerInitOnce.Do(func() {
|
|
||||||
logrusPackage = getPackageName(runtime.FuncForPC(pcs[0]).Name())
|
|
||||||
|
|
||||||
// now that we have the cache, we can skip a minimum count of known-logrus functions
|
|
||||||
// XXX this is dubious, the number of frames may vary store an entry in a logger interface
|
|
||||||
minimumCallerDepth = knownLogrusFrames
|
|
||||||
})
|
|
||||||
|
|
||||||
for f, again := frames.Next(); again; f, again = frames.Next() {
|
for f, again := frames.Next(); again; f, again = frames.Next() {
|
||||||
pkg := getPackageName(f.Function)
|
pkg := getPackageName(f.Function)
|
||||||
|
|
||||||
|
|
|
@ -743,3 +743,20 @@ func TestReportCallerOnTextFormatter(t *testing.T) {
|
||||||
l.Formatter.(*TextFormatter).DisableColors = true
|
l.Formatter.(*TextFormatter).DisableColors = true
|
||||||
l.WithFields(Fields{"func": "func", "file": "file"}).Info("test")
|
l.WithFields(Fields{"func": "func", "file": "file"}).Info("test")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetReportCallerRace(t *testing.T) {
|
||||||
|
l := New()
|
||||||
|
l.Out = ioutil.Discard
|
||||||
|
l.SetReportCaller(true)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(100)
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
go func() {
|
||||||
|
l.Error("Some Error")
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue