Browse code

Protect jsonfilelog writes with mutex

Signed-off-by: Alexander Morozov <lk4d4@docker.com>

Alexander Morozov authored on 2015/03/19 04:52:42
Showing 1 changed files
... ...
@@ -3,6 +3,7 @@ package jsonfilelog
3 3
 import (
4 4
 	"bytes"
5 5
 	"os"
6
+	"sync"
6 7
 
7 8
 	"github.com/docker/docker/daemon/logger"
8 9
 	"github.com/docker/docker/pkg/jsonlog"
... ...
@@ -12,7 +13,8 @@ import (
12 12
 // JSON objects to file
13 13
 type JSONFileLogger struct {
14 14
 	buf *bytes.Buffer
15
-	f   *os.File // store for closing
15
+	f   *os.File   // store for closing
16
+	mu  sync.Mutex // protects buffer
16 17
 }
17 18
 
18 19
 // New creates new JSONFileLogger which writes to filename
... ...
@@ -29,13 +31,20 @@ func New(filename string) (logger.Logger, error) {
29 29
 
30 30
 // Log converts logger.Message to jsonlog.JSONLog and serializes it to file
31 31
 func (l *JSONFileLogger) Log(msg *logger.Message) error {
32
+	l.mu.Lock()
33
+	defer l.mu.Unlock()
32 34
 	err := (&jsonlog.JSONLog{Log: string(msg.Line) + "\n", Stream: msg.Source, Created: msg.Timestamp}).MarshalJSONBuf(l.buf)
33 35
 	if err != nil {
34 36
 		return err
35 37
 	}
36 38
 	l.buf.WriteByte('\n')
37 39
 	_, err = l.buf.WriteTo(l.f)
38
-	return err
40
+	if err != nil {
41
+		// this buffer is screwed, replace it with another to avoid races
42
+		l.buf = bytes.NewBuffer(nil)
43
+		return err
44
+	}
45
+	return nil
39 46
 }
40 47
 
41 48
 // Close closes underlying file