From 6b073ba1ad905e7629f8b54dab6b71ead44ec0c6 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Wed, 14 Dec 2022 14:59:33 +0000 Subject: [PATCH 1/2] chore(writer): implement zapcore.WriterSyncer to avoid wrapping writer --- gelf.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gelf.go b/gelf.go index ba96c18..7fcbe0d 100644 --- a/gelf.go +++ b/gelf.go @@ -94,6 +94,9 @@ var ( // chunkedMagicBytes chunked message magic bytes. // See http://docs.graylog.org/en/2.4/pages/gelf.html. chunkedMagicBytes = []byte{0x1e, 0x0f} + + // Ensure *writer implements zapcore.WriteSyncer. + _ zapcore.WriteSyncer = (*writer)(nil) ) // NewCore zap core constructor. @@ -142,7 +145,7 @@ func NewCore(options ...Option) (_ zapcore.Core, err error) { var core = zapcore.NewCore( zapcore.NewJSONEncoder(conf.encoder), - zapcore.AddSync(w), + w, conf.enabler, ) @@ -380,6 +383,11 @@ func (w *writer) Write(buf []byte) (n int, err error) { return n, nil } +// Sync is a no-op, but required to implement the zapcore.WriteSyncer interface. +func (w *writer) Sync() error { + return nil +} + // Close implementation of io.WriteCloser. func (*writeCloser) Close() error { return nil From dc1209bd7f2d7839f75dbbb8d18184686fad237a Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Wed, 14 Dec 2022 15:06:04 +0000 Subject: [PATCH 2/2] feat(options): add WriteSyncers option allowing use of multiple writers Allows adding both os.Stdout and os.Stderr as a writer target in addition to GELF. Anything which implements zapcore.WriteSyncer can be added. --- gelf.go | 16 +++++++++++++++- gelf_test.go | 10 ++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/gelf.go b/gelf.go index 7fcbe0d..20b3b72 100644 --- a/gelf.go +++ b/gelf.go @@ -143,9 +143,15 @@ func NewCore(options ...Option) (_ zapcore.Core, err error) { return nil, err } + var ws zapcore.WriteSyncer = w + if len(conf.writeSyncers) > 0 { + var writers = append([]zapcore.WriteSyncer{w}, conf.writeSyncers...) + ws = zapcore.NewMultiWriteSyncer(writers...) + } + var core = zapcore.NewCore( zapcore.NewJSONEncoder(conf.encoder), - w, + ws, conf.enabler, ) @@ -277,6 +283,14 @@ func EncodeName(value zapcore.NameEncoder) Option { }) } +// WriteSyncers sets additional zapcore.WriteSyncers on the core. +func WriteSyncers(value ...zapcore.WriteSyncer) Option { + return optionFunc(func(conf *optionConf) error { + conf.writeSyncers = append(conf.writeSyncers, value...) + return nil + }) +} + // NewReflectedEncoder set zapcore.EncoderConfig NewReflectedEncoder property. func NewReflectedEncoder(value func(io.Writer) zapcore.ReflectedEncoder) Option { return optionFunc(func(conf *optionConf) error { diff --git a/gelf_test.go b/gelf_test.go index 1913fdc..71e2b96 100644 --- a/gelf_test.go +++ b/gelf_test.go @@ -3,6 +3,7 @@ package gelf_test import ( "encoding/json" "io" + "os" "testing" "github.com/stretchr/testify/assert" @@ -147,6 +148,15 @@ func TestEncodeName(t *testing.T) { assert.Implements(t, (*zapcore.Core)(nil), core, "Expect zapcore.Core") } +func TestWriteSyncers(t *testing.T) { + var core, err = gelf.NewCore( + gelf.WriteSyncers(os.Stderr), + ) + + assert.Nil(t, err, "Unexpected error") + assert.Implements(t, (*zapcore.Core)(nil), core, "Expect zapcore.Core") +} + func TestNewReflectedEncoder(t *testing.T) { var newEncoder = func(writer io.Writer) zapcore.ReflectedEncoder { return json.NewEncoder(writer)