I’m trying to build a customized logger that keeps log messages below Error level in a buffer and flushes the buffer only after encountering an Error.
The problem is that I don’t know how to trigger the flushing of the logs to the output (Sync method) when encountering an Error.
The below code is an attempt to do so:
func CustomLogger() {
// First, define our level-handling logic.
lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < activationLevel
})
//define the output of the logs
customWriteSyncer := Buffer(os.Stdout)
consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
//creates a Core that writes logs to a WriteSyncer
core := zapcore.NewCore(consoleEncoder, customWriteSyncer, lowPriority)
logger := zap.New(core)
defer logger.Sync()
Logger = logger
}
type BufferWriterSync struct {
buf *bufio.Writer
}
func Buffer(ws zapcore.WriteSyncer) zapcore.WriteSyncer {
bw := &BufferWriterSync{
buf: bufio.NewWriter(ws),
}
ws = zapcore.Lock(bw)
return ws
}
// Sync syncs data to output
func (w BufferWriterSync) Sync() error {
return w.buf.Flush()
}
// Write writes data to buffer
func (w BufferWriterSync) Write(p []byte) (int, error) {
return w.buf.Write(p)
}
Example, when performing:
logger.Info("some Info message")
this message ends up in the buffer of bufio.Writer and the Info message is not displayedlogger.Info("some Info message2")
this message ends up in the buffer of bufio.Writer and the Info message is not displayedlogger.Error("some Error message")
only when encountering logging of an error all the accumulated logs from the buffered must be flushed to the output, based on the above code example it should go toos.Stdout
Expected output:
some Info message
some Info message2
some Error message
NOTE: The functionality that I am trying to achieve is similar to fingers_crossed feature that is present in Php Symfony framework.