forked from mirror/logrus
store a runtime.Frame in Entry instead of the caller function name
This commit is contained in:
parent
975c406ddb
commit
ec57031db1
16
entry.go
16
entry.go
|
@ -61,7 +61,7 @@ type Entry struct {
|
||||||
Level Level
|
Level Level
|
||||||
|
|
||||||
// Calling method, with package name
|
// Calling method, with package name
|
||||||
Caller string
|
Caller *runtime.Frame
|
||||||
|
|
||||||
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
|
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
|
||||||
Message string
|
Message string
|
||||||
|
@ -144,10 +144,11 @@ 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() (method string) {
|
func getCaller() *runtime.Frame {
|
||||||
// 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])
|
||||||
|
|
||||||
// cache this package's fully-qualified name
|
// cache this package's fully-qualified name
|
||||||
callerInitOnce.Do(func() {
|
callerInitOnce.Do(func() {
|
||||||
|
@ -158,24 +159,23 @@ func getCaller() (method string) {
|
||||||
minimumCallerDepth = knownLogrusFrames
|
minimumCallerDepth = knownLogrusFrames
|
||||||
})
|
})
|
||||||
|
|
||||||
for i := 0; i < depth; i++ {
|
for f, again := frames.Next(); again; f, again = frames.Next() {
|
||||||
fullFuncName := runtime.FuncForPC(pcs[i]).Name()
|
pkg := getPackageName(f.Function)
|
||||||
pkg := getPackageName(fullFuncName)
|
|
||||||
|
|
||||||
// If the caller isn't part of this package, we're done
|
// If the caller isn't part of this package, we're done
|
||||||
if pkg != logrusPackage {
|
if pkg != logrusPackage {
|
||||||
return fullFuncName
|
return &f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we got here, we failed to find the caller's context
|
// if we got here, we failed to find the caller's context
|
||||||
return ""
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry Entry) HasCaller() (has bool) {
|
func (entry Entry) HasCaller() (has bool) {
|
||||||
return entry.Logger != nil &&
|
return entry.Logger != nil &&
|
||||||
entry.Logger.ReportCaller &&
|
entry.Logger.ReportCaller &&
|
||||||
entry.Caller != ""
|
entry.Caller != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is not declared with a pointer value because otherwise
|
// This function is not declared with a pointer value because otherwise
|
||||||
|
|
|
@ -82,7 +82,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||||
if entry.HasCaller() {
|
if entry.HasCaller() {
|
||||||
data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller
|
data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
|
||||||
}
|
}
|
||||||
|
|
||||||
var b *bytes.Buffer
|
var b *bytes.Buffer
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -167,8 +168,8 @@ func TestFieldsInNestedDictionary(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
logEntry := WithFields(Fields{
|
logEntry := WithFields(Fields{
|
||||||
"level": "level",
|
"level": "level",
|
||||||
"test": "test",
|
"test": "test",
|
||||||
})
|
})
|
||||||
logEntry.Level = InfoLevel
|
logEntry.Level = InfoLevel
|
||||||
|
|
||||||
|
@ -291,7 +292,7 @@ func TestFieldClashWithCaller(t *testing.T) {
|
||||||
SetReportCaller(true)
|
SetReportCaller(true)
|
||||||
formatter := &JSONFormatter{}
|
formatter := &JSONFormatter{}
|
||||||
e := WithField("func", "howdy pardner")
|
e := WithField("func", "howdy pardner")
|
||||||
e.Caller = "somefunc"
|
e.Caller = &runtime.Frame{Function: "somefunc"}
|
||||||
b, err := formatter.Format(e)
|
b, err := formatter.Format(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Unable to format entry: ", err)
|
t.Fatal("Unable to format entry: ", err)
|
||||||
|
|
|
@ -208,7 +208,7 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
||||||
caller := ""
|
caller := ""
|
||||||
|
|
||||||
if entry.HasCaller() {
|
if entry.HasCaller() {
|
||||||
caller = fmt.Sprintf(" %s()", entry.Caller)
|
caller = fmt.Sprintf(" %s()", entry.Caller.Function)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.DisableTimestamp {
|
if f.DisableTimestamp {
|
||||||
|
|
Loading…
Reference in New Issue