From 8103e491b600641f873e573d578aaa6bd4ba2c81 Mon Sep 17 00:00:00 2001 From: Cyril Tovena Date: Mon, 10 May 2021 17:07:12 +0200 Subject: [PATCH] Fixes docker driver that would panic when closed. This is happening because it can still received log, but the client might be already closed. Fixes #3705 Signed-off-by: Cyril Tovena --- clients/cmd/docker-driver/loki.go | 15 +++++++++++++++ clients/cmd/docker-driver/loki_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 clients/cmd/docker-driver/loki_test.go diff --git a/clients/cmd/docker-driver/loki.go b/clients/cmd/docker-driver/loki.go index be16486594db..f8538c6b67a2 100644 --- a/clients/cmd/docker-driver/loki.go +++ b/clients/cmd/docker-driver/loki.go @@ -2,10 +2,12 @@ package main import ( "bytes" + "sync" "github.com/docker/docker/daemon/logger" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" + "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/model" @@ -24,6 +26,9 @@ type loki struct { labels model.LabelSet logger log.Logger + closed bool + mutex sync.RWMutex + stop func() } @@ -59,6 +64,13 @@ func New(logCtx logger.Info, logger log.Logger) (logger.Logger, error) { // Log implements `logger.Logger` func (l *loki) Log(m *logger.Message) error { + l.mutex.RLock() + defer l.mutex.RUnlock() + + if l.closed { + return errors.New("client closed") + } + if len(bytes.Fields(m.Line)) == 0 { level.Debug(l.logger).Log("msg", "ignoring empty line", "line", string(m.Line)) return nil @@ -84,7 +96,10 @@ func (l *loki) Name() string { // Log implements `logger.Logger` func (l *loki) Close() error { + l.mutex.Lock() + defer l.mutex.Unlock() l.stop() l.client.StopNow() + l.closed = true return nil } diff --git a/clients/cmd/docker-driver/loki_test.go b/clients/cmd/docker-driver/loki_test.go new file mode 100644 index 000000000000..85fe1cefc833 --- /dev/null +++ b/clients/cmd/docker-driver/loki_test.go @@ -0,0 +1,25 @@ +package main + +import ( + "testing" + "time" + + util_log "github.com/cortexproject/cortex/pkg/util/log" + "github.com/docker/docker/daemon/logger" + "github.com/stretchr/testify/require" +) + +func Test_loki_LogWhenClosed(t *testing.T) { + l, err := New(logger.Info{ + Config: map[string]string{ + "loki-url": "http://localhost:3000", + }, + }, util_log.Logger) + require.Nil(t, err) + msg := logger.NewMessage() + msg.Line = []byte(`foo`) + msg.Timestamp = time.Now() + require.Nil(t, l.Log(msg)) + require.Nil(t, l.Close()) + require.NotNil(t, l.Log(msg)) +}