From 7d248fa1b145f2d5aea8d147c6eea99fc0461db7 Mon Sep 17 00:00:00 2001 From: Ariel Simulevski Date: Fri, 10 Apr 2020 12:42:19 +0200 Subject: [PATCH 1/2] Add loggers that take functions as input --- .gitignore | 2 ++ example_function_test.go | 26 ++++++++++++++++++++ exported.go | 45 ++++++++++++++++++++++++++++++++++ logger.go | 52 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 example_function_test.go diff --git a/.gitignore b/.gitignore index 6b7d7d1e8..1fb13abeb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ logrus vendor + +.idea/ diff --git a/example_function_test.go b/example_function_test.go new file mode 100644 index 000000000..f61460eca --- /dev/null +++ b/example_function_test.go @@ -0,0 +1,26 @@ +package logrus_test + +import ( + "fmt" + log "github.com/sirupsen/logrus" + "testing" +) + +func TestLogger_LogFn(t *testing.T) { + log.SetFormatter(&log.JSONFormatter{}) + log.SetLevel(log.WarnLevel) + + log.InfoFn(func() []interface{} { + fmt.Println("This is never run") + return []interface{} { + "Hello", + } + }) + + log.ErrorFn(func() []interface{} { + fmt.Println("This runs") + return []interface{} { + "Oopsi", + } + }) +} diff --git a/exported.go b/exported.go index 42b04f6c8..017c30ce6 100644 --- a/exported.go +++ b/exported.go @@ -134,6 +134,51 @@ func Fatal(args ...interface{}) { std.Fatal(args...) } +// TraceFn logs a message from a func at level Trace on the standard logger. +func TraceFn(fn LogFunction) { + std.TraceFn(fn) +} + +// DebugFn logs a message from a func at level Debug on the standard logger. +func DebugFn(fn LogFunction) { + std.DebugFn(fn) +} + +// PrintFn logs a message from a func at level Info on the standard logger. +func PrintFn(fn LogFunction) { + std.PrintFn(fn) +} + +// InfoFn logs a message from a func at level Info on the standard logger. +func InfoFn(fn LogFunction) { + std.InfoFn(fn) +} + +// WarnFn logs a message from a func at level Warn on the standard logger. +func WarnFn(fn LogFunction) { + std.WarnFn(fn) +} + +// WarningFn logs a message from a func at level Warn on the standard logger. +func WarningFn(fn LogFunction) { + std.WarningFn(fn) +} + +// ErrorFn logs a message from a func at level Error on the standard logger. +func ErrorFn(fn LogFunction) { + std.ErrorFn(fn) +} + +// PanicFn logs a message from a func at level Panic on the standard logger. +func PanicFn(fn LogFunction) { + std.PanicFn(fn) +} + +// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1. +func FatalFn(fn LogFunction) { + std.FatalFn(fn) +} + // Tracef logs a message at level Trace on the standard logger. func Tracef(format string, args ...interface{}) { std.Tracef(format, args...) diff --git a/logger.go b/logger.go index 6fdda748e..dae5e5708 100644 --- a/logger.go +++ b/logger.go @@ -9,6 +9,11 @@ import ( "time" ) +// LogFunction For big messages, it can be more efficient to pass a function +// and only call it if the log level is actually enables rather than +// generating the log message and then checking if the level is enabled +type LogFunction func()[]interface{} + type Logger struct { // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a // file, or leave it default which is `os.Stderr`. You can also set this to @@ -195,6 +200,14 @@ func (logger *Logger) Log(level Level, args ...interface{}) { } } +func (logger *Logger) LogFn(level Level, fn LogFunction) { + if logger.IsLevelEnabled(level) { + entry := logger.newEntry() + entry.Log(level, fn()...) + logger.releaseEntry(entry) + } +} + func (logger *Logger) Trace(args ...interface{}) { logger.Log(TraceLevel, args...) } @@ -234,6 +247,45 @@ func (logger *Logger) Panic(args ...interface{}) { logger.Log(PanicLevel, args...) } +func (logger *Logger) TraceFn(fn LogFunction) { + logger.LogFn(TraceLevel, fn) +} + +func (logger *Logger) DebugFn(fn LogFunction) { + logger.LogFn(DebugLevel, fn) +} + +func (logger *Logger) InfoFn(fn LogFunction) { + logger.LogFn(InfoLevel, fn) +} + +func (logger *Logger) PrintFn(fn LogFunction) { + entry := logger.newEntry() + entry.Print(fn()...) + logger.releaseEntry(entry) +} + +func (logger *Logger) WarnFn(fn LogFunction) { + logger.LogFn(WarnLevel, fn) +} + +func (logger *Logger) WarningFn(fn LogFunction) { + logger.WarnFn(fn) +} + +func (logger *Logger) ErrorFn(fn LogFunction) { + logger.LogFn(ErrorLevel, fn) +} + +func (logger *Logger) FatalFn(fn LogFunction) { + logger.LogFn(FatalLevel, fn) + logger.Exit(1) +} + +func (logger *Logger) PanicFn(fn LogFunction) { + logger.LogFn(PanicLevel, fn) +} + func (logger *Logger) Logln(level Level, args ...interface{}) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() From ba4da53cffb0ed6b42e5cfa334a011e55448f7db Mon Sep 17 00:00:00 2001 From: David Bariod Date: Tue, 19 May 2020 17:02:33 +0200 Subject: [PATCH 2/2] Improve tests for logger.*Fn functions --- example_function_test.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/example_function_test.go b/example_function_test.go index f61460eca..dda890d83 100644 --- a/example_function_test.go +++ b/example_function_test.go @@ -1,26 +1,31 @@ package logrus_test import ( - "fmt" - log "github.com/sirupsen/logrus" "testing" + + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" ) func TestLogger_LogFn(t *testing.T) { log.SetFormatter(&log.JSONFormatter{}) log.SetLevel(log.WarnLevel) + notCalled := 0 log.InfoFn(func() []interface{} { - fmt.Println("This is never run") - return []interface{} { + notCalled++ + return []interface{}{ "Hello", } }) + assert.Equal(t, 0, notCalled) + called := 0 log.ErrorFn(func() []interface{} { - fmt.Println("This runs") - return []interface{} { + called++ + return []interface{}{ "Oopsi", } }) + assert.Equal(t, 1, called) }