daemon/logger: Global buffer pools

Moved the buffer pools in json-file and local logging drivers to the
whole driver scope. It is more efficient to have a pool for the whole
driver rather than for each logger instance.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
Paweł Gronowski 2022-05-30 10:17:31 +02:00
parent 4e09933aed
commit 8fe2a68698
2 changed files with 23 additions and 27 deletions

View file

@ -20,12 +20,18 @@ import (
// Name is the name of the file that the jsonlogger logs to.
const Name = "json-file"
// Every buffer will have to store the same constant json structure with the message
// len(`{"log":"","stream:"stdout","time":"2000-01-01T00:00:00.000000000Z"}\n`) = 68.
// So let's start with a buffer bigger than this.
const initialBufSize = 128
var buffersPool = sync.Pool{New: func() interface{} { return bytes.NewBuffer(make([]byte, 0, initialBufSize)) }}
// JSONFileLogger is Logger implementation for default Docker logging.
type JSONFileLogger struct {
writer *loggerutils.LogFile
tag string // tag values requested by the user to log
extra json.RawMessage
buffersPool sync.Pool
writer *loggerutils.LogFile
tag string // tag values requested by the user to log
extra json.RawMessage
}
func init() {
@ -104,28 +110,18 @@ func New(info logger.Info) (logger.Logger, error) {
}
return &JSONFileLogger{
writer: writer,
tag: tag,
extra: extra,
buffersPool: makePool(),
writer: writer,
tag: tag,
extra: extra,
}, nil
}
func makePool() sync.Pool {
// Every buffer will have to store the same constant json structure and the message
// len(`{"log":"","stream:"stdout","time":"2000-01-01T00:00:00.000000000Z"}\n`) = 68
// So let's start with a buffer bigger than this
const initialBufSize = 128
return sync.Pool{New: func() interface{} { return bytes.NewBuffer(make([]byte, 0, initialBufSize)) }}
}
// Log converts logger.Message to jsonlog.JSONLog and serializes it to file.
func (l *JSONFileLogger) Log(msg *logger.Message) error {
defer logger.PutMessage(msg)
buf := l.buffersPool.Get().(*bytes.Buffer)
buf := buffersPool.Get().(*bytes.Buffer)
buf.Reset()
defer l.buffersPool.Put(buf)
defer buffersPool.Put(buf)
if err := marshalMessage(msg, l.extra, buf); err != nil {
return err

View file

@ -29,6 +29,11 @@ const (
defaultCompressLogs = true
)
var buffersPool = sync.Pool{New: func() interface{} {
b := make([]byte, initialBufSize)
return &b
}}
// LogOptKeys are the keys names used for log opts passed in to initialize the driver.
var LogOptKeys = map[string]bool{
"max-file": true,
@ -56,8 +61,7 @@ func init() {
}
type driver struct {
logfile *loggerutils.LogFile
buffersPool sync.Pool
logfile *loggerutils.LogFile
}
// New creates a new local logger
@ -135,10 +139,6 @@ func newDriver(logPath string, cfg *CreateConfig) (logger.Logger, error) {
}
return &driver{
logfile: lf,
buffersPool: sync.Pool{New: func() interface{} {
b := make([]byte, initialBufSize)
return &b
}},
}, nil
}
@ -148,8 +148,8 @@ func (d *driver) Name() string {
func (d *driver) Log(msg *logger.Message) error {
defer logger.PutMessage(msg)
buf := d.buffersPool.Get().(*[]byte)
defer d.buffersPool.Put(buf)
buf := buffersPool.Get().(*[]byte)
defer buffersPool.Put(buf)
err := marshal(msg, buf)
if err != nil {