From 9479a5ba3e6d937668a129c2481a14b733c9a2bf Mon Sep 17 00:00:00 2001 From: Aleksandr Razumov Date: Thu, 24 Dec 2020 14:30:59 +0300 Subject: [PATCH] Add WithTimeSource Option Allow passing current time source. --- logger.go | 8 ++++++-- options.go | 9 +++++++++ time_source_test.go | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 time_source_test.go diff --git a/logger.go b/logger.go index bdcc5d666..e5741cc4f 100644 --- a/logger.go +++ b/logger.go @@ -51,6 +51,9 @@ type Logger struct { addStack zapcore.LevelEnabler callerSkip int + + // now returns current time, default is time.Now. + now func() time.Time } // New constructs a new Logger from the provided zapcore.Core and Options. If @@ -71,6 +74,7 @@ func New(core zapcore.Core, options ...Option) *Logger { core: core, errorOutput: zapcore.Lock(os.Stderr), addStack: zapcore.FatalLevel + 1, + now: time.Now, } return log.WithOptions(options...) } @@ -270,7 +274,7 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // log message will actually be written somewhere. ent := zapcore.Entry{ LoggerName: log.name, - Time: time.Now(), + Time: log.now(), Level: lvl, Message: msg, } @@ -307,7 +311,7 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { if log.addCaller { frame, defined := getCallerFrame(log.callerSkip + callerSkipOffset) if !defined { - fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC()) + fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", log.now().UTC()) log.errorOutput.Sync() } diff --git a/options.go b/options.go index 0135c2092..59c9387d9 100644 --- a/options.go +++ b/options.go @@ -22,6 +22,7 @@ package zap import ( "fmt" + "time" "go.uber.org/zap/zapcore" ) @@ -138,3 +139,11 @@ func OnFatal(action zapcore.CheckWriteAction) Option { log.onFatal = action }) } + +// WithTimeSource configures the Logger to get current time from provided +// function when creating entry. +func WithTimeSource(now func() time.Time) Option { + return optionFunc(func(log *Logger) { + log.now = now + }) +} diff --git a/time_source_test.go b/time_source_test.go new file mode 100644 index 000000000..5f2785fd2 --- /dev/null +++ b/time_source_test.go @@ -0,0 +1,20 @@ +package zap + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest/observer" +) + +func TestWithTimeSource(t *testing.T) { + date := time.Date(2077, 1, 23, 10, 15, 13, 441, time.UTC) + now := func() time.Time { return date } + withLogger(t, DebugLevel, []Option{WithTimeSource(now)}, func(log *Logger, logs *observer.ObservedLogs) { + log.Info("") + require.Equal(t, 1, logs.Len(), "Expected only one log entry to be written.") + assert.Equal(t, date, logs.All()[0].Entry.Time, "Unexpected entry time.") + }) +}