Skip to content

Commit

Permalink
store a runtime.Frame in Entry instead of the caller function name
Browse files Browse the repository at this point in the history
  • Loading branch information
dgsb committed Oct 28, 2018
1 parent 975c406 commit ec57031
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 13 deletions.
16 changes: 8 additions & 8 deletions entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type Entry struct {
Level Level

// Calling method, with package name
Caller string
Caller *runtime.Frame

// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
Message string
Expand Down Expand Up @@ -144,10 +144,11 @@ func getPackageName(f string) string {
}

// 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
pcs := make([]uintptr, maximumCallerDepth)
depth := runtime.Callers(minimumCallerDepth, pcs)
frames := runtime.CallersFrames(pcs[:depth])

// cache this package's fully-qualified name
callerInitOnce.Do(func() {
Expand All @@ -158,24 +159,23 @@ func getCaller() (method string) {
minimumCallerDepth = knownLogrusFrames
})

for i := 0; i < depth; i++ {
fullFuncName := runtime.FuncForPC(pcs[i]).Name()
pkg := getPackageName(fullFuncName)
for f, again := frames.Next(); again; f, again = frames.Next() {
pkg := getPackageName(f.Function)

// If the caller isn't part of this package, we're done
if pkg != logrusPackage {
return fullFuncName
return &f
}
}

// if we got here, we failed to find the caller's context
return ""
return nil
}

func (entry Entry) HasCaller() (has bool) {
return entry.Logger != nil &&
entry.Logger.ReportCaller &&
entry.Caller != ""
entry.Caller != nil
}

// This function is not declared with a pointer value because otherwise
Expand Down
2 changes: 1 addition & 1 deletion json_formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
if entry.HasCaller() {
data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller
data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
}

var b *bytes.Buffer
Expand Down
7 changes: 4 additions & 3 deletions json_formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"runtime"
"strings"
"testing"
)
Expand Down Expand Up @@ -167,8 +168,8 @@ func TestFieldsInNestedDictionary(t *testing.T) {
}

logEntry := WithFields(Fields{
"level": "level",
"test": "test",
"level": "level",
"test": "test",
})
logEntry.Level = InfoLevel

Expand Down Expand Up @@ -291,7 +292,7 @@ func TestFieldClashWithCaller(t *testing.T) {
SetReportCaller(true)
formatter := &JSONFormatter{}
e := WithField("func", "howdy pardner")
e.Caller = "somefunc"
e.Caller = &runtime.Frame{Function: "somefunc"}
b, err := formatter.Format(e)
if err != nil {
t.Fatal("Unable to format entry: ", err)
Expand Down
2 changes: 1 addition & 1 deletion text_formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
caller := ""

if entry.HasCaller() {
caller = fmt.Sprintf(" %s()", entry.Caller)
caller = fmt.Sprintf(" %s()", entry.Caller.Function)
}

if f.DisableTimestamp {
Expand Down

0 comments on commit ec57031

Please sign in to comment.