Add the ability to capture the logger caller file and line number
Fixes #34, #22
This commit is contained in:
parent
fcbdf23e9e
commit
27e0a22cbc
14
context.go
14
context.go
|
@ -302,3 +302,17 @@ func (c Context) Interface(key string, i interface{}) Context {
|
||||||
c.l.context = json.AppendInterface(json.AppendKey(c.l.context, key), i)
|
c.l.context = json.AppendInterface(json.AppendKey(c.l.context, key), i)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type callerHook struct{}
|
||||||
|
|
||||||
|
func (ch callerHook) Run(e *Event, level Level, msg string) {
|
||||||
|
e.caller(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ch = callerHook{}
|
||||||
|
|
||||||
|
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
|
||||||
|
func (c Context) Caller() Context {
|
||||||
|
c.l = c.l.Hook(ch)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
19
event.go
19
event.go
|
@ -4,6 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -561,3 +563,20 @@ func (e *Event) Interface(key string, i interface{}) *Event {
|
||||||
e.buf = json.AppendInterface(json.AppendKey(e.buf, key), i)
|
e.buf = json.AppendInterface(json.AppendKey(e.buf, key), i)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
|
||||||
|
func (e *Event) Caller() *Event {
|
||||||
|
return e.caller(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Event) caller(skip int) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
_, file, line, ok := runtime.Caller(skip)
|
||||||
|
if !ok {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.buf = json.AppendString(json.AppendKey(e.buf, CallerFieldName), file+":"+strconv.Itoa(line))
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@ var (
|
||||||
// ErrorFieldName is the field name used for error fields.
|
// ErrorFieldName is the field name used for error fields.
|
||||||
ErrorFieldName = "error"
|
ErrorFieldName = "error"
|
||||||
|
|
||||||
|
// CallerFieldName is the field name used for caller field.
|
||||||
|
CallerFieldName = "caller"
|
||||||
|
|
||||||
// TimeFieldFormat defines the time format of the Time field type.
|
// TimeFieldFormat defines the time format of the Time field type.
|
||||||
// If set to an empty string, the time is formatted as an UNIX timestamp
|
// If set to an empty string, the time is formatted as an UNIX timestamp
|
||||||
// as integer.
|
// as integer.
|
||||||
|
|
17
log_test.go
17
log_test.go
|
@ -3,7 +3,9 @@ package zerolog
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -74,7 +76,7 @@ func TestInfo(t *testing.T) {
|
||||||
|
|
||||||
func TestWith(t *testing.T) {
|
func TestWith(t *testing.T) {
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
log := New(out).With().
|
ctx := New(out).With().
|
||||||
Str("foo", "bar").
|
Str("foo", "bar").
|
||||||
AnErr("some_err", nil).
|
AnErr("some_err", nil).
|
||||||
Err(errors.New("some error")).
|
Err(errors.New("some error")).
|
||||||
|
@ -91,10 +93,12 @@ func TestWith(t *testing.T) {
|
||||||
Uint64("uint64", 10).
|
Uint64("uint64", 10).
|
||||||
Float32("float32", 11).
|
Float32("float32", 11).
|
||||||
Float64("float64", 12).
|
Float64("float64", 12).
|
||||||
Time("time", time.Time{}).
|
Time("time", time.Time{})
|
||||||
Logger()
|
_, file, line, _ := runtime.Caller(0)
|
||||||
|
caller := fmt.Sprintf("%s:%d", file, line+3)
|
||||||
|
log := ctx.Caller().Logger()
|
||||||
log.Log().Msg("")
|
log.Log().Msg("")
|
||||||
if got, want := out.String(), `{"foo":"bar","error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"time":"0001-01-01T00:00:00Z"}`+"\n"; got != want {
|
if got, want := out.String(), `{"foo":"bar","error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
|
||||||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
|
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +136,10 @@ func TestFields(t *testing.T) {
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
log := New(out)
|
log := New(out)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
_, file, line, _ := runtime.Caller(0)
|
||||||
|
caller := fmt.Sprintf("%s:%d", file, line+3)
|
||||||
log.Log().
|
log.Log().
|
||||||
|
Caller().
|
||||||
Str("string", "foo").
|
Str("string", "foo").
|
||||||
Bytes("bytes", []byte("bar")).
|
Bytes("bytes", []byte("bar")).
|
||||||
AnErr("some_err", nil).
|
AnErr("some_err", nil).
|
||||||
|
@ -154,7 +161,7 @@ func TestFields(t *testing.T) {
|
||||||
Time("time", time.Time{}).
|
Time("time", time.Time{}).
|
||||||
TimeDiff("diff", now, now.Add(-10*time.Second)).
|
TimeDiff("diff", now, now.Add(-10*time.Second)).
|
||||||
Msg("")
|
Msg("")
|
||||||
if got, want := out.String(), `{"string":"foo","bytes":"bar","error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"dur":1000,"time":"0001-01-01T00:00:00Z","diff":10000}`+"\n"; got != want {
|
if got, want := out.String(), `{"caller":"`+caller+`","string":"foo","bytes":"bar","error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"dur":1000,"time":"0001-01-01T00:00:00Z","diff":10000}`+"\n"; got != want {
|
||||||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
|
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue