Defer formatting of log values in Levelf(), Levelln()

The Level() family of log methods defer formatting of log
values until it is confident that the log level needs them.
This change allows that deferral to happen at the Levelf()
and Levelln() levels too.

This commit also adds benchmarks to demonstrate the improved
performance of these functions
This commit is contained in:
Anthony Bishopric 2014-03-19 09:02:00 -07:00
parent f9af352362
commit 9f6da0e77c
2 changed files with 86 additions and 16 deletions

View File

@ -129,67 +129,79 @@ func (entry *Entry) Panic(args ...interface{}) {
// Entry Printf family functions // Entry Printf family functions
func (entry *Entry) Debugf(format string, args ...interface{}) { func (entry *Entry) Debugf(format string, args ...interface{}) {
if entry.logger.Level >= Debug {
entry.Debug(fmt.Sprintf(format, args...)) entry.Debug(fmt.Sprintf(format, args...))
} }
}
func (entry *Entry) Infof(format string, args ...interface{}) { func (entry *Entry) Infof(format string, args ...interface{}) {
if entry.logger.Level >= Info {
entry.Info(fmt.Sprintf(format, args...)) entry.Info(fmt.Sprintf(format, args...))
} }
}
func (entry *Entry) Printf(format string, args ...interface{}) { func (entry *Entry) Printf(format string, args ...interface{}) {
entry.Info(fmt.Sprintf(format, args...)) entry.Info(format, args...)
} }
func (entry *Entry) Warnf(format string, args ...interface{}) { func (entry *Entry) Warnf(format string, args ...interface{}) {
if entry.logger.Level >= Warn {
entry.Warn(fmt.Sprintf(format, args...)) entry.Warn(fmt.Sprintf(format, args...))
} }
}
func (entry *Entry) Warningf(format string, args ...interface{}) { func (entry *Entry) Warningf(format string, args ...interface{}) {
entry.Warn(fmt.Sprintf(format, args...)) entry.Warnf(format, args...)
} }
func (entry *Entry) Errorf(format string, args ...interface{}) { func (entry *Entry) Errorf(format string, args ...interface{}) {
if entry.logger.Level >= Error {
entry.Error(fmt.Sprintf(format, args...)) entry.Error(fmt.Sprintf(format, args...))
} }
}
func (entry *Entry) Fatalf(format string, args ...interface{}) { func (entry *Entry) Fatalf(format string, args ...interface{}) {
if entry.logger.Level >= Fatal {
entry.Fatal(fmt.Sprintf(format, args...)) entry.Fatal(fmt.Sprintf(format, args...))
} }
}
func (entry *Entry) Panicf(format string, args ...interface{}) { func (entry *Entry) Panicf(format string, args ...interface{}) {
if entry.logger.Level >= Panic {
entry.Panic(fmt.Sprintf(format, args...)) entry.Panic(fmt.Sprintf(format, args...))
} }
}
// Entry Println family functions // Entry Println family functions
func (entry *Entry) Debugln(args ...interface{}) { func (entry *Entry) Debugln(args ...interface{}) {
entry.Debug(fmt.Sprint(args...)) entry.Debug(args...)
} }
func (entry *Entry) Infoln(args ...interface{}) { func (entry *Entry) Infoln(args ...interface{}) {
entry.Info(fmt.Sprint(args...)) entry.Info(args...)
} }
func (entry *Entry) Println(args ...interface{}) { func (entry *Entry) Println(args ...interface{}) {
entry.Info(fmt.Sprint(args...)) entry.Info(args...)
} }
func (entry *Entry) Warnln(args ...interface{}) { func (entry *Entry) Warnln(args ...interface{}) {
entry.Warn(fmt.Sprint(args...)) entry.Warn(args...)
} }
func (entry *Entry) Warningln(args ...interface{}) { func (entry *Entry) Warningln(args ...interface{}) {
entry.Warn(fmt.Sprint(args...)) entry.Warn(args...)
} }
func (entry *Entry) Errorln(args ...interface{}) { func (entry *Entry) Errorln(args ...interface{}) {
entry.Error(fmt.Sprint(args...)) entry.Error(args...)
} }
func (entry *Entry) Fatalln(args ...interface{}) { func (entry *Entry) Fatalln(args ...interface{}) {
entry.Fatal(fmt.Sprint(args...)) entry.Fatal(args...)
} }
func (entry *Entry) Panicln(args ...interface{}) { func (entry *Entry) Panicln(args ...interface{}) {
entry.Panic(fmt.Sprint(args...)) entry.Panic(args...)
} }

View File

@ -3,7 +3,9 @@ package logrus
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -50,3 +52,59 @@ func TestWarn(t *testing.T) {
assert.Equal(t, fields["level"], "warning") assert.Equal(t, fields["level"], "warning")
}) })
} }
type SlowString string
func (s SlowString) String() string {
time.Sleep(time.Millisecond)
return string(s)
}
func getLogAtLevel(l Level) *Logger {
log := New()
log.Level = l
log.Out = ioutil.Discard
return log
}
func BenchmarkLevelDisplayed(b *testing.B) {
log := getLogAtLevel(Info)
for i := 0; i < b.N; i++ {
log.Info(SlowString("foo"))
}
}
func BenchmarkLevelHidden(b *testing.B) {
log := getLogAtLevel(Info)
for i := 0; i < b.N; i++ {
log.Debug(SlowString("foo"))
}
}
func BenchmarkLevelfDisplayed(b *testing.B) {
log := getLogAtLevel(Info)
for i := 0; i < b.N; i++ {
log.Infof("%s", SlowString("foo"))
}
}
func BenchmarkLevelfHidden(b *testing.B) {
log := getLogAtLevel(Info)
for i := 0; i < b.N; i++ {
log.Debugf("%s", SlowString("foo"))
}
}
func BenchmarkLevellnDisplayed(b *testing.B) {
log := getLogAtLevel(Info)
for i := 0; i < b.N; i++ {
log.Infoln(SlowString("foo"))
}
}
func BenchmarkLevellnHidden(b *testing.B) {
log := getLogAtLevel(Info)
for i := 0; i < b.N; i++ {
log.Debugln(SlowString("foo"))
}
}