diff --git a/zapcore/write_syncer.go b/zapcore/write_syncer.go index 2a9237640..e0a7db80e 100644 --- a/zapcore/write_syncer.go +++ b/zapcore/write_syncer.go @@ -34,6 +34,12 @@ type WriteSyncer interface { Sync() error } +// LockedWriteSyncer is the interface that groups sync.Locker and WriteSyncer methods. +type LockedWriteSyncer interface { + sync.Locker + WriteSyncer +} + // AddSync converts an io.Writer to a WriteSyncer. It attempts to be // intelligent: if the concrete type of the io.Writer implements WriteSyncer, // we'll use the existing Sync method. If it doesn't, we'll add a no-op Sync. @@ -54,7 +60,7 @@ type lockedWriteSyncer struct { // Lock wraps a WriteSyncer in a mutex to make it safe for concurrent use. In // particular, *os.Files must be locked before use. func Lock(ws WriteSyncer) WriteSyncer { - if _, ok := ws.(*lockedWriteSyncer); ok { + if _, ok := ws.(LockedWriteSyncer); ok { // no need to layer on another lock return ws } diff --git a/zapcore/write_syncer_test.go b/zapcore/write_syncer_test.go index 43c28cef1..10a34f6a8 100644 --- a/zapcore/write_syncer_test.go +++ b/zapcore/write_syncer_test.go @@ -56,6 +56,16 @@ func TestAddSyncWriteSyncer(t *testing.T) { assert.Error(t, ws.Sync(), "Expected to propagate errors from concrete type's Sync method.") } +func TestLockedWriteSyncerInterface(t *testing.T) { + buf := &bytes.Buffer{} + ws := AddSync(buf) + var lws WriteSyncer = &lockedWriteSyncer{ws: ws} + + _, ok := lws.(LockedWriteSyncer) + require.True(t, ok, "Wrong implementation of the builtin lockedWriteSyncer") + require.Equal(t, lws, Lock(lws), "Unnessessary wrapped lock for locked WriteSyncer") +} + func TestAddSyncWriter(t *testing.T) { // If we pass a plain io.Writer, make sure that we still get a WriteSyncer // with a no-op Sync.