diff --git a/formatter.go b/formatter.go index db37848..4088837 100644 --- a/formatter.go +++ b/formatter.go @@ -10,6 +10,7 @@ const ( FieldKeyTime = "time" FieldKeyLogrusError = "logrus_error" FieldKeyFunc = "func" + FieldKeyFile = "file" ) // The Formatter interface is used to implement a custom Formatter. It takes an @@ -69,5 +70,9 @@ func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) { if l, ok := data[funcKey]; ok { data["fields."+funcKey] = l } + fileKey := fieldMap.resolve(FieldKeyFile) + if l, ok := data[fileKey]; ok { + data["fields."+fileKey] = l + } } } diff --git a/json_formatter.go b/json_formatter.go index f5d45bb..2605753 100644 --- a/json_formatter.go +++ b/json_formatter.go @@ -83,6 +83,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() if entry.HasCaller() { data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function + data[f.FieldMap.resolve(FieldKeyFile)] = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) } var b *bytes.Buffer diff --git a/logrus_test.go b/logrus_test.go index 3b1d256..27cddaf 100644 --- a/logrus_test.go +++ b/logrus_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "io/ioutil" + "os" "sync" "testing" "time" @@ -339,11 +340,14 @@ func TestNestedLoggingReportsCorrectCaller(t *testing.T) { err := json.Unmarshal(buffer.Bytes(), &fields) require.NoError(t, err, "should have decoded first message") - assert.Equal(t, len(fields), 5, "should have msg/time/level/func/context fields") + assert.Equal(t, 6, len(fields), "should have msg/time/level/func/context fields") assert.Equal(t, "looks delicious", fields["msg"]) assert.Equal(t, "eating raw fish", fields["context"]) assert.Equal(t, "github.com/sirupsen/logrus_test.TestNestedLoggingReportsCorrectCaller", fields["func"]) + cwd, err := os.Getwd() + require.NoError(t, err) + assert.Equal(t, cwd+"/logrus_test.go:339", fields["file"]) buffer.Reset() @@ -361,7 +365,7 @@ func TestNestedLoggingReportsCorrectCaller(t *testing.T) { err = json.Unmarshal(buffer.Bytes(), &fields) assert.NoError(t, err, "should have decoded second message") - assert.Equal(t, 10, len(fields), "should have all builtin fields plus foo,bar,baz,...") + assert.Equal(t, 11, len(fields), "should have all builtin fields plus foo,bar,baz,...") assert.Equal(t, "Stubblefield", fields["Clyde"]) assert.Equal(t, "Starks", fields["Jab'o"]) assert.Equal(t, "https://www.youtube.com/watch?v=V5DTznu-9v0", fields["uri"]) @@ -371,6 +375,8 @@ func TestNestedLoggingReportsCorrectCaller(t *testing.T) { assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry") assert.Equal(t, "github.com/sirupsen/logrus_test.TestNestedLoggingReportsCorrectCaller", fields["func"]) + require.NoError(t, err) + assert.Equal(t, cwd+"/logrus_test.go:364", fields["file"]) logger.ReportCaller = false // return to default value } diff --git a/text_formatter.go b/text_formatter.go index 354387c..c5f9ca3 100644 --- a/text_formatter.go +++ b/text_formatter.go @@ -126,7 +126,8 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError)) } if entry.HasCaller() { - fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFunc)) + fixedKeys = append(fixedKeys, + f.FieldMap.resolve(FieldKeyFunc), f.FieldMap.resolve(FieldKeyFile)) } if !f.DisableSorting { @@ -172,6 +173,10 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { value = entry.Message case f.FieldMap.resolve(FieldKeyLogrusError): value = entry.err + case f.FieldMap.resolve(FieldKeyFunc): + value = entry.Caller.Function + case f.FieldMap.resolve(FieldKeyFile): + value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) default: value = entry.Data[key] } @@ -208,7 +213,8 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin caller := "" if entry.HasCaller() { - caller = fmt.Sprintf(" %s()", entry.Caller.Function) + caller = fmt.Sprintf("%s:%d %s()", + entry.Caller.File, entry.Caller.Line, entry.Caller.Function) } if f.DisableTimestamp {