mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
933a87236f
Before this change, the log decoder function provided by the log driver to logfile would not be able to re-use buffers, causing undeeded allocations and memory bloat for dockerd. This change introduces an interface that allows the log driver to manage it's memory usge more effectively. This only affects json-file and local log drivers. `json-file` still is not great just because of how the json decoder in the stdlib works. `local` is significantly improved. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
95 lines
2.3 KiB
Go
95 lines
2.3 KiB
Go
package jsonfilelog // import "github.com/docker/docker/daemon/logger/jsonfilelog"
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/docker/docker/daemon/logger"
|
|
"gotest.tools/v3/assert"
|
|
"gotest.tools/v3/fs"
|
|
)
|
|
|
|
func BenchmarkJSONFileLoggerReadLogs(b *testing.B) {
|
|
tmp := fs.NewDir(b, "bench-jsonfilelog")
|
|
defer tmp.Remove()
|
|
|
|
jsonlogger, err := New(logger.Info{
|
|
ContainerID: "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657",
|
|
LogPath: tmp.Join("container.log"),
|
|
Config: map[string]string{
|
|
"labels": "first,second",
|
|
},
|
|
ContainerLabels: map[string]string{
|
|
"first": "label_value",
|
|
"second": "label_foo",
|
|
},
|
|
})
|
|
assert.NilError(b, err)
|
|
defer jsonlogger.Close()
|
|
|
|
msg := &logger.Message{
|
|
Line: []byte("Line that thinks that it is log line from docker\n"),
|
|
Source: "stderr",
|
|
Timestamp: time.Now().UTC(),
|
|
}
|
|
|
|
buf := bytes.NewBuffer(nil)
|
|
assert.NilError(b, marshalMessage(msg, nil, buf))
|
|
b.SetBytes(int64(buf.Len()))
|
|
|
|
b.ResetTimer()
|
|
|
|
chError := make(chan error, b.N+1)
|
|
go func() {
|
|
for i := 0; i < b.N; i++ {
|
|
chError <- jsonlogger.Log(msg)
|
|
}
|
|
chError <- jsonlogger.Close()
|
|
}()
|
|
|
|
lw := jsonlogger.(*JSONFileLogger).ReadLogs(logger.ReadConfig{Follow: true})
|
|
for {
|
|
select {
|
|
case <-lw.Msg:
|
|
case <-lw.WatchProducerGone():
|
|
return
|
|
case err := <-chError:
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEncodeDecode(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
m1 := &logger.Message{Line: []byte("hello 1"), Timestamp: time.Now(), Source: "stdout"}
|
|
m2 := &logger.Message{Line: []byte("hello 2"), Timestamp: time.Now(), Source: "stdout"}
|
|
m3 := &logger.Message{Line: []byte("hello 3"), Timestamp: time.Now(), Source: "stdout"}
|
|
|
|
buf := bytes.NewBuffer(nil)
|
|
assert.Assert(t, marshalMessage(m1, nil, buf))
|
|
assert.Assert(t, marshalMessage(m2, nil, buf))
|
|
assert.Assert(t, marshalMessage(m3, nil, buf))
|
|
|
|
dec := decodeFunc(buf)
|
|
defer dec.Close()
|
|
|
|
msg, err := dec.Decode()
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, string(msg.Line) == "hello 1\n", string(msg.Line))
|
|
|
|
msg, err = dec.Decode()
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, string(msg.Line) == "hello 2\n")
|
|
|
|
msg, err = dec.Decode()
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, string(msg.Line) == "hello 3\n")
|
|
|
|
_, err = dec.Decode()
|
|
assert.Assert(t, err == io.EOF)
|
|
}
|