2018-04-05 16:42:31 +00:00
|
|
|
package cache // import "github.com/docker/docker/daemon/logger/loggerutils/cache"
|
|
|
|
|
|
|
|
import (
|
2018-04-09 19:35:24 +00:00
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/docker/docker/api/types/container"
|
2018-04-05 16:42:31 +00:00
|
|
|
"github.com/docker/docker/daemon/logger"
|
|
|
|
"github.com/docker/docker/daemon/logger/local"
|
2018-04-09 19:35:24 +00:00
|
|
|
units "github.com/docker/go-units"
|
|
|
|
"github.com/pkg/errors"
|
2018-04-05 16:42:31 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
2018-04-09 19:35:24 +00:00
|
|
|
const (
|
|
|
|
// DriverName is the name of the driver used for local log caching
|
|
|
|
DriverName = local.Name
|
|
|
|
|
|
|
|
cachePrefix = "cache-"
|
|
|
|
cacheDisabledKey = cachePrefix + "disabled"
|
|
|
|
)
|
|
|
|
|
|
|
|
var builtInCacheLogOpts = map[string]bool{
|
|
|
|
cacheDisabledKey: true,
|
|
|
|
}
|
|
|
|
|
2018-04-05 16:42:31 +00:00
|
|
|
// WithLocalCache wraps the passed in logger with a logger caches all writes locally
|
|
|
|
// in addition to writing to the passed in logger.
|
2018-04-09 19:35:24 +00:00
|
|
|
func WithLocalCache(l logger.Logger, info logger.Info) (logger.Logger, error) {
|
|
|
|
initLogger, err := logger.GetLogDriver(DriverName)
|
2018-04-05 16:42:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-04-09 19:35:24 +00:00
|
|
|
|
|
|
|
cacher, err := initLogger(info)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "error initializing local log cache driver")
|
|
|
|
}
|
|
|
|
|
|
|
|
if info.Config["mode"] == container.LogModeUnset || container.LogMode(info.Config["mode"]) == container.LogModeNonBlock {
|
|
|
|
var size int64 = -1
|
|
|
|
if s, exists := info.Config["max-buffer-size"]; exists {
|
|
|
|
size, err = units.RAMInBytes(s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cacher = logger.NewRingLogger(cacher, info, size)
|
|
|
|
}
|
|
|
|
|
2018-04-05 16:42:31 +00:00
|
|
|
return &loggerWithCache{
|
2018-04-09 19:35:24 +00:00
|
|
|
l: l,
|
|
|
|
cache: cacher,
|
2018-04-05 16:42:31 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type loggerWithCache struct {
|
|
|
|
l logger.Logger
|
|
|
|
cache logger.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *loggerWithCache) Log(msg *logger.Message) error {
|
2018-04-09 19:35:24 +00:00
|
|
|
// copy the message as the original will be reset once the call to `Log` is complete
|
2018-04-05 16:42:31 +00:00
|
|
|
dup := logger.NewMessage()
|
|
|
|
dumbCopyMessage(dup, msg)
|
2018-04-09 19:35:24 +00:00
|
|
|
|
2018-04-05 16:42:31 +00:00
|
|
|
if err := l.l.Log(msg); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return l.cache.Log(dup)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *loggerWithCache) Name() string {
|
|
|
|
return l.l.Name()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *loggerWithCache) ReadLogs(config logger.ReadConfig) *logger.LogWatcher {
|
|
|
|
return l.cache.(logger.LogReader).ReadLogs(config)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *loggerWithCache) Close() error {
|
|
|
|
err := l.l.Close()
|
|
|
|
if err := l.cache.Close(); err != nil {
|
|
|
|
logrus.WithError(err).Warn("error while shutting cache logger")
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-04-09 19:35:24 +00:00
|
|
|
// ShouldUseCache reads the log opts to determine if caching should be enabled
|
|
|
|
func ShouldUseCache(cfg map[string]string) bool {
|
|
|
|
if cfg[cacheDisabledKey] == "" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
b, err := strconv.ParseBool(cfg[cacheDisabledKey])
|
|
|
|
if err != nil {
|
|
|
|
// This shouldn't happen since the values are validated before hand.
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return !b
|
|
|
|
}
|
|
|
|
|
2018-04-05 16:42:31 +00:00
|
|
|
// dumbCopyMessage is a bit of a fake copy but avoids extra allocations which
|
|
|
|
// are not necessary for this use case.
|
|
|
|
func dumbCopyMessage(dst, src *logger.Message) {
|
|
|
|
dst.Source = src.Source
|
|
|
|
dst.Timestamp = src.Timestamp
|
|
|
|
dst.PLogMetaData = src.PLogMetaData
|
|
|
|
dst.Err = src.Err
|
|
|
|
dst.Attrs = src.Attrs
|
2018-04-09 19:35:24 +00:00
|
|
|
dst.Line = append(dst.Line[:0], src.Line...)
|
2018-04-05 16:42:31 +00:00
|
|
|
}
|