zerolog icon indicating copy to clipboard operation
zerolog copied to clipboard

ConsoleWriter Write implementation doesn't behave nicely with CBOR/-binary_log build

Open johnbartholomew opened this issue 4 years ago • 0 comments

When building with -tags binary_log to enable CBOR format output, the ConsoleWriter implementation mostly still works; it converts the CBOR data to JSON and formats it as normal. However it returns the wrong length value from its io.Writer Write implementation. This is detected if using io.MultiWriter to wrap the ConsoleWriter.

The Write implementation is here: https://github.com/rs/zerolog/blob/v1.20.0/console.go#L85-L118 It takes a parameter p []byte, and at the end returns return len(p), err which looks correct. But on line 98 it decoded from CBOR to JSON and put the JSON string into p. So the returned length doesn't match the original length, which breaks the contract for Write.

You might ask: Why would you want to combine -binary_log/cbor output with ConsoleWriter? Basically I want to use cbor for the normal log and always write that (to file), but in non-production mode I want to tee to the console with pretty-printing. So I build with -binary_log and log to an io.MultiWriter which tee's to the output file and to a ConsoleWriter, and in production mode I skip the MultiWriter and just log directly to the file.

Test case:

package main

import (
	"io"

	"github.com/rs/zerolog"
)

func main() {
	con := zerolog.NewConsoleWriter()
	m := io.MultiWriter(con)
	log := zerolog.New(m).With().Timestamp().Logger()
	log.Info().Str("foo", "bar").Msg("qux")
}

Output:

$ go build -tags binary_log && ./testcase
7:18PM INF qux foo=bar
zerolog: could not write event: short write

johnbartholomew avatar Nov 07 '20 19:11 johnbartholomew