~craftyguy/logger

bd34503053fb146f24dc587a40bbd4fac0968f71 — Clayton Craft 10 months ago 55b2d6f master
print: return if string would be hidden by current log level

This effectively makes printing a no-op when the configured log level
would stop it from being printed anyways.

This speeds up calls to these functions significantly, shown by the
benchmarks this commit also adds:

goos: linux
goarch: amd64
pkg: git.sr.ht/~craftyguy/logger
cpu: Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz
BenchmarkDebugfLogLevelINFO-12          55498520                18.44 ns/op            0 B/op          0 allocs/op
BenchmarkDebugfLogLevelDEBUG-12          1644188               656.5 ns/op           408 B/op          8 allocs/op
2 files changed, 46 insertions(+), 0 deletions(-)

M logger.go
M logger_test.go
M logger.go => logger.go +24 -0
@@ 83,48 83,72 @@ func (l *Logger) SetMinLevel(level logutils.LogLevel) {
func (l *Logger) Printf(f string, s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[INFO] < l.minlevel {
		return
	}
	l.log.Print(format(INFO, l.noColor, fmt.Sprintf(f, s...)))
}

func (l *Logger) Println(s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[INFO] < l.minlevel {
		return
	}
	l.log.Println(format(INFO, l.noColor, s...))
}

func (l *Logger) Debugf(f string, s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[DEBUG] < l.minlevel {
		return
	}
	l.log.Print(format(DEBUG, l.noColor, fmt.Sprintf(f, s...)))
}

func (l *Logger) Debugln(s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[DEBUG] < l.minlevel {
		return
	}
	l.log.Println(format(DEBUG, l.noColor, s...))
}

func (l *Logger) Warnf(f string, s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[WARN] < l.minlevel {
		return
	}
	l.log.Print(format(WARN, l.noColor, fmt.Sprintf(f, s...)))
}

func (l *Logger) Warnln(s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[WARN] < l.minlevel {
		return
	}
	l.log.Println(format(WARN, l.noColor, s...))
}

func (l *Logger) Errorf(f string, s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[ERROR] < l.minlevel {
		return
	}
	l.log.Print(format(ERROR, l.noColor, fmt.Sprintf(f, s...)))
}

func (l *Logger) Errorln(s ...interface{}) {
	l.RLock()
	defer l.RUnlock()
	if levels[ERROR] < l.minlevel {
		return
	}
	l.log.Println(format(ERROR, l.noColor, s...))
}


M logger_test.go => logger_test.go +22 -0
@@ 4,6 4,7 @@
package logger

import (
	"io"
	"testing"
)



@@ 34,3 35,24 @@ func TestFormat(t *testing.T) {
		}
	})
}

// Benchmark calling print when the log level is higher than the log level that
// this print's "level"
func BenchmarkDebugfLogLevelINFO(b *testing.B) {
	s := "this is an important message about something important. it's important, ok?"
	l := New(io.Discard, true, true)
	l.SetMinLevel(INFO)
	for i := 0; i < b.N; i++ {
		l.Debugf(s)
	}
}

// Benchmark print when the log level is lower than its "level"
func BenchmarkDebugfLogLevelDEBUG(b *testing.B) {
	s := "this is an important message about something important. it's important, ok?"
	l := New(io.Discard, true, true)
	l.SetMinLevel(DEBUG)
	for i := 0; i < b.N; i++ {
		l.Debugf(s)
	}
}