|
@@ -1,22 +1,55 @@
|
|
package cache // import "github.com/docker/docker/daemon/logger/loggerutils/cache"
|
|
package cache // import "github.com/docker/docker/daemon/logger/loggerutils/cache"
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
+ "strconv"
|
|
|
|
+
|
|
|
|
+ "github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/daemon/logger"
|
|
"github.com/docker/docker/daemon/logger"
|
|
"github.com/docker/docker/daemon/logger/local"
|
|
"github.com/docker/docker/daemon/logger/local"
|
|
|
|
+ units "github.com/docker/go-units"
|
|
|
|
+ "github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+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,
|
|
|
|
+}
|
|
|
|
+
|
|
// WithLocalCache wraps the passed in logger with a logger caches all writes locally
|
|
// WithLocalCache wraps the passed in logger with a logger caches all writes locally
|
|
// in addition to writing to the passed in logger.
|
|
// in addition to writing to the passed in logger.
|
|
-func WithLocalCache(l logger.Logger, logInfo logger.Info) (logger.Logger, error) {
|
|
|
|
- localLogger, err := local.New(logInfo)
|
|
|
|
|
|
+func WithLocalCache(l logger.Logger, info logger.Info) (logger.Logger, error) {
|
|
|
|
+ initLogger, err := logger.GetLogDriver(DriverName)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ 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)
|
|
|
|
+ }
|
|
|
|
+
|
|
return &loggerWithCache{
|
|
return &loggerWithCache{
|
|
- l: l,
|
|
|
|
- // TODO(@cpuguy83): Should this be configurable?
|
|
|
|
- cache: logger.NewRingLogger(localLogger, logInfo, -1),
|
|
|
|
|
|
+ l: l,
|
|
|
|
+ cache: cacher,
|
|
}, nil
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -26,9 +59,10 @@ type loggerWithCache struct {
|
|
}
|
|
}
|
|
|
|
|
|
func (l *loggerWithCache) Log(msg *logger.Message) error {
|
|
func (l *loggerWithCache) Log(msg *logger.Message) error {
|
|
- // copy the message since the underlying logger will return the passed in message to the message pool
|
|
|
|
|
|
+ // copy the message as the original will be reset once the call to `Log` is complete
|
|
dup := logger.NewMessage()
|
|
dup := logger.NewMessage()
|
|
dumbCopyMessage(dup, msg)
|
|
dumbCopyMessage(dup, msg)
|
|
|
|
+
|
|
if err := l.l.Log(msg); err != nil {
|
|
if err := l.l.Log(msg); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -51,6 +85,19 @@ func (l *loggerWithCache) Close() error {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 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
|
|
|
|
+}
|
|
|
|
+
|
|
// dumbCopyMessage is a bit of a fake copy but avoids extra allocations which
|
|
// dumbCopyMessage is a bit of a fake copy but avoids extra allocations which
|
|
// are not necessary for this use case.
|
|
// are not necessary for this use case.
|
|
func dumbCopyMessage(dst, src *logger.Message) {
|
|
func dumbCopyMessage(dst, src *logger.Message) {
|
|
@@ -59,5 +106,5 @@ func dumbCopyMessage(dst, src *logger.Message) {
|
|
dst.PLogMetaData = src.PLogMetaData
|
|
dst.PLogMetaData = src.PLogMetaData
|
|
dst.Err = src.Err
|
|
dst.Err = src.Err
|
|
dst.Attrs = src.Attrs
|
|
dst.Attrs = src.Attrs
|
|
- dst.Line = src.Line
|
|
|
|
|
|
+ dst.Line = append(dst.Line[:0], src.Line...)
|
|
}
|
|
}
|