gogo-zap

How can I use custom time function in zap logger library


I'm working with the Zap logger library in Go and I'm trying to achieve a custom timestamp generation approach for logging. Specifically, I want to use my own time function instead of relying on the system time.

While I've explored the documentation, I haven't been able to pinpoint the solution for implementing a custom time function effectively.

In essence, I'm aiming for functionality similar to this pseudo-code:

// Sudo code

var tmFn func()time.Time
// more code

logger.SetTimeFunc(tmFn)

I'd appreciate any insights or guidance on how to achieve this customization within the Zap logger library.


Solution

  • You can use WithClock option to define your own clock, providing the time function you want. E.g. with a constant clock (always returning a date like 2077-01-23T10:15:13Z). This example is based on clock_test.go from zap library.

    package main
    
    import (
        "time"
    
        "go.uber.org/zap"
        "go.uber.org/zap/zapcore"
    )
    
    type constantClock time.Time
    
    func (c constantClock) Now() time.Time { return time.Time(c) }
    func (c constantClock) NewTicker(d time.Duration) *time.Ticker {
        return &time.Ticker{}
    }
    
    func main() {
        date := time.Date(2077, 1, 23, 10, 15, 13, 441, time.UTC) // clock will always return that date
        clock := constantClock(date)
    
        config := zap.NewProductionConfig()
        // this is just for sugar, to display a readable date instead of an epoch time
        config.EncoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout(time.RFC3339)
    
        logger, _ := config.Build()
        logger = logger.WithOptions(zap.WithClock(clock))
        defer logger.Sync()
    
        logger.Info("Hello")
    }
    

    You can play with that code here: https://go.dev/play/p/8oLQm7mXrlD, and this will print:

    {"level":"info","ts":"2077-01-23T10:15:13Z","caller":"sandbox1129194476/prog.go:29","msg":"Hello"}

    From there, you can customize your clock like you need (Now() and NewTicker() methods) to provide the time you will expect.