diff --git a/entry.go b/entry.go index 04673a0..1e97f99 100644 --- a/entry.go +++ b/entry.go @@ -8,6 +8,9 @@ import ( "time" ) +// Defines the key when adding errors using WithError. +var ErrorKey = "error" + // An entry is the final or intermediate Logrus logging entry. It contains all // the fields passed with WithField{,s}. It's finally logged when Debug, Info, // Warn, Error, Fatal or Panic is called on it. These objects can be reused and @@ -53,6 +56,19 @@ func (entry *Entry) String() (string, error) { return reader.String(), err } +// ToError returns the field value of ErrorKey (nil) +func (entry *Entry) ToError() error { + if err, ok := entry.Data[ErrorKey].(error); ok { + return err + } + return nil +} + +// Add an error as single field (using the key defined in ErrorKey) to the Entry. +func (entry *Entry) WithError(err error) *Entry { + return entry.WithField(ErrorKey, err) +} + // Add a single field to the Entry. func (entry *Entry) WithField(key string, value interface{}) *Entry { return entry.WithFields(Fields{key: value}) @@ -106,36 +122,40 @@ func (entry Entry) log(level Level, msg string) { } } -func (entry *Entry) Debug(args ...interface{}) { +func (entry *Entry) Debug(args ...interface{}) *Entry { if entry.Logger.Level >= DebugLevel { entry.log(DebugLevel, fmt.Sprint(args...)) } + return entry } -func (entry *Entry) Print(args ...interface{}) { - entry.Info(args...) +func (entry *Entry) Print(args ...interface{}) *Entry { + return entry.Info(args...) } -func (entry *Entry) Info(args ...interface{}) { +func (entry *Entry) Info(args ...interface{}) *Entry { if entry.Logger.Level >= InfoLevel { entry.log(InfoLevel, fmt.Sprint(args...)) } + return entry } -func (entry *Entry) Warn(args ...interface{}) { +func (entry *Entry) Warn(args ...interface{}) *Entry { if entry.Logger.Level >= WarnLevel { entry.log(WarnLevel, fmt.Sprint(args...)) } + return entry } -func (entry *Entry) Warning(args ...interface{}) { - entry.Warn(args...) +func (entry *Entry) Warning(args ...interface{}) *Entry { + return entry.Warn(args...) } -func (entry *Entry) Error(args ...interface{}) { +func (entry *Entry) Error(args ...interface{}) *Entry { if entry.Logger.Level >= ErrorLevel { entry.log(ErrorLevel, fmt.Sprint(args...)) } + return entry } func (entry *Entry) Fatal(args ...interface{}) { @@ -154,36 +174,40 @@ func (entry *Entry) Panic(args ...interface{}) { // Entry Printf family functions -func (entry *Entry) Debugf(format string, args ...interface{}) { +func (entry *Entry) Debugf(format string, args ...interface{}) *Entry { if entry.Logger.Level >= DebugLevel { entry.Debug(fmt.Sprintf(format, args...)) } + return entry } -func (entry *Entry) Infof(format string, args ...interface{}) { +func (entry *Entry) Infof(format string, args ...interface{}) *Entry { if entry.Logger.Level >= InfoLevel { entry.Info(fmt.Sprintf(format, args...)) } + return entry } -func (entry *Entry) Printf(format string, args ...interface{}) { - entry.Infof(format, args...) +func (entry *Entry) Printf(format string, args ...interface{}) *Entry { + return entry.Infof(format, args...) } -func (entry *Entry) Warnf(format string, args ...interface{}) { +func (entry *Entry) Warnf(format string, args ...interface{}) *Entry { if entry.Logger.Level >= WarnLevel { entry.Warn(fmt.Sprintf(format, args...)) } + return entry } -func (entry *Entry) Warningf(format string, args ...interface{}) { - entry.Warnf(format, args...) +func (entry *Entry) Warningf(format string, args ...interface{}) *Entry { + return entry.Warnf(format, args...) } -func (entry *Entry) Errorf(format string, args ...interface{}) { +func (entry *Entry) Errorf(format string, args ...interface{}) *Entry { if entry.Logger.Level >= ErrorLevel { entry.Error(fmt.Sprintf(format, args...)) } + return entry } func (entry *Entry) Fatalf(format string, args ...interface{}) { @@ -201,36 +225,40 @@ func (entry *Entry) Panicf(format string, args ...interface{}) { // Entry Println family functions -func (entry *Entry) Debugln(args ...interface{}) { +func (entry *Entry) Debugln(args ...interface{}) *Entry { if entry.Logger.Level >= DebugLevel { entry.Debug(entry.sprintlnn(args...)) } + return entry } -func (entry *Entry) Infoln(args ...interface{}) { +func (entry *Entry) Infoln(args ...interface{}) *Entry { if entry.Logger.Level >= InfoLevel { entry.Info(entry.sprintlnn(args...)) } + return entry } -func (entry *Entry) Println(args ...interface{}) { - entry.Infoln(args...) +func (entry *Entry) Println(args ...interface{}) *Entry { + return entry.Infoln(args...) } -func (entry *Entry) Warnln(args ...interface{}) { +func (entry *Entry) Warnln(args ...interface{}) *Entry { if entry.Logger.Level >= WarnLevel { entry.Warn(entry.sprintlnn(args...)) } + return entry } -func (entry *Entry) Warningln(args ...interface{}) { - entry.Warnln(args...) +func (entry *Entry) Warningln(args ...interface{}) *Entry { + return entry.Warnln(args...) } -func (entry *Entry) Errorln(args ...interface{}) { +func (entry *Entry) Errorln(args ...interface{}) *Entry { if entry.Logger.Level >= ErrorLevel { entry.Error(entry.sprintlnn(args...)) } + return entry } func (entry *Entry) Fatalln(args ...interface{}) { diff --git a/entry_test.go b/entry_test.go index 98717df..3473ffb 100644 --- a/entry_test.go +++ b/entry_test.go @@ -8,6 +8,45 @@ import ( "github.com/stretchr/testify/assert" ) +var err = fmt.Errorf("kaboom at layer %d", 4711) + +func TestToError(t *testing.T) { + + assert := assert.New(t) + + ctx := WithField("foo", "bar") + assert.Equal(nil, ctx.Debug("Hello").ToError()) + + ctx.Data[ErrorKey] = "error" + assert.Equal(nil, ctx.Debug("Hello").ToError()) + + ctx = ctx.WithError(err) + assert.Equal(err, ctx.Debug("Hello").ToError()) + +} + +func TestEntryWithError(t *testing.T) { + + assert := assert.New(t) + + defer func() { + ErrorKey = "error" + }() + + assert.Equal(err, WithError(err).Data["error"]) + + logger := New() + logger.Out = &bytes.Buffer{} + entry := NewEntry(logger) + + assert.Equal(err, entry.WithError(err).Data["error"]) + + ErrorKey = "err" + + assert.Equal(err, entry.WithError(err).Data["err"]) + +} + func TestEntryPanicln(t *testing.T) { errBoom := fmt.Errorf("boom time") diff --git a/exported.go b/exported.go index a67e1b8..9a0120a 100644 --- a/exported.go +++ b/exported.go @@ -48,6 +48,11 @@ func AddHook(hook Hook) { std.Hooks.Add(hook) } +// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +func WithError(err error) *Entry { + return std.WithField(ErrorKey, err) +} + // WithField creates an entry from the standard logger and adds a field to // it. If you want multiple fields, use `WithFields`. //