2018-02-05 21:05:59 +00:00
|
|
|
package logger // import "github.com/docker/docker/daemon/logger"
|
2015-04-09 04:23:30 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2017-04-11 21:21:21 +00:00
|
|
|
"sort"
|
2015-04-09 04:23:30 +00:00
|
|
|
"sync"
|
2016-11-23 02:55:27 +00:00
|
|
|
|
|
|
|
containertypes "github.com/docker/docker/api/types/container"
|
2016-11-14 18:53:53 +00:00
|
|
|
"github.com/docker/docker/pkg/plugingetter"
|
2019-08-05 14:37:47 +00:00
|
|
|
units "github.com/docker/go-units"
|
2016-11-23 02:55:27 +00:00
|
|
|
"github.com/pkg/errors"
|
2015-04-09 04:23:30 +00:00
|
|
|
)
|
|
|
|
|
2015-07-21 22:26:52 +00:00
|
|
|
// Creator builds a logging driver instance with given context.
|
2016-11-26 05:08:34 +00:00
|
|
|
type Creator func(Info) (Logger, error)
|
2015-04-09 04:23:30 +00:00
|
|
|
|
2015-07-21 22:26:52 +00:00
|
|
|
// LogOptValidator checks the options specific to the underlying
|
|
|
|
// logging implementation.
|
2015-07-01 00:40:13 +00:00
|
|
|
type LogOptValidator func(cfg map[string]string) error
|
|
|
|
|
2015-04-09 04:23:30 +00:00
|
|
|
type logdriverFactory struct {
|
2015-07-01 00:40:13 +00:00
|
|
|
registry map[string]Creator
|
|
|
|
optValidator map[string]LogOptValidator
|
|
|
|
m sync.Mutex
|
2015-04-09 04:23:30 +00:00
|
|
|
}
|
|
|
|
|
2017-04-11 21:21:21 +00:00
|
|
|
func (lf *logdriverFactory) list() []string {
|
|
|
|
ls := make([]string, 0, len(lf.registry))
|
|
|
|
lf.m.Lock()
|
|
|
|
for name := range lf.registry {
|
|
|
|
ls = append(ls, name)
|
|
|
|
}
|
|
|
|
lf.m.Unlock()
|
|
|
|
sort.Strings(ls)
|
|
|
|
return ls
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListDrivers gets the list of registered log driver names
|
|
|
|
func ListDrivers() []string {
|
|
|
|
return factory.list()
|
|
|
|
}
|
|
|
|
|
2015-04-09 04:23:30 +00:00
|
|
|
func (lf *logdriverFactory) register(name string, c Creator) error {
|
2020-04-10 17:05:42 +00:00
|
|
|
registered, err := lf.driverRegistered(name)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if registered {
|
2015-04-09 04:23:30 +00:00
|
|
|
return fmt.Errorf("logger: log driver named '%s' is already registered", name)
|
|
|
|
}
|
2016-03-12 12:50:37 +00:00
|
|
|
|
|
|
|
lf.m.Lock()
|
2015-04-09 04:23:30 +00:00
|
|
|
lf.registry[name] = c
|
2016-03-12 12:50:37 +00:00
|
|
|
lf.m.Unlock()
|
2015-04-09 04:23:30 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-04-10 17:05:42 +00:00
|
|
|
func (lf *logdriverFactory) driverRegistered(name string) (bool, error) {
|
2016-03-12 12:50:37 +00:00
|
|
|
lf.m.Lock()
|
|
|
|
_, ok := lf.registry[name]
|
|
|
|
lf.m.Unlock()
|
2016-11-14 18:53:53 +00:00
|
|
|
if !ok {
|
|
|
|
if pluginGetter != nil { // this can be nil when the init functions are running
|
2020-04-10 17:05:42 +00:00
|
|
|
l, err := getPlugin(name, plugingetter.Lookup)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
if l != nil {
|
|
|
|
return true, nil
|
2016-11-14 18:53:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-10 17:05:42 +00:00
|
|
|
return ok, nil
|
2016-03-12 12:50:37 +00:00
|
|
|
}
|
|
|
|
|
2015-07-01 00:40:13 +00:00
|
|
|
func (lf *logdriverFactory) registerLogOptValidator(name string, l LogOptValidator) error {
|
|
|
|
lf.m.Lock()
|
|
|
|
defer lf.m.Unlock()
|
|
|
|
|
|
|
|
if _, ok := lf.optValidator[name]; ok {
|
2015-07-21 22:26:52 +00:00
|
|
|
return fmt.Errorf("logger: log validator named '%s' is already registered", name)
|
2015-07-01 00:40:13 +00:00
|
|
|
}
|
|
|
|
lf.optValidator[name] = l
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-04-09 04:23:30 +00:00
|
|
|
func (lf *logdriverFactory) get(name string) (Creator, error) {
|
|
|
|
lf.m.Lock()
|
|
|
|
defer lf.m.Unlock()
|
|
|
|
|
|
|
|
c, ok := lf.registry[name]
|
2016-11-14 18:53:53 +00:00
|
|
|
if ok {
|
|
|
|
return c, nil
|
2015-04-09 04:23:30 +00:00
|
|
|
}
|
2016-11-14 18:53:53 +00:00
|
|
|
|
|
|
|
c, err := getPlugin(name, plugingetter.Acquire)
|
|
|
|
return c, errors.Wrapf(err, "logger: no log driver named '%s' is registered", name)
|
2015-04-09 04:23:30 +00:00
|
|
|
}
|
|
|
|
|
2015-07-01 00:40:13 +00:00
|
|
|
func (lf *logdriverFactory) getLogOptValidator(name string) LogOptValidator {
|
|
|
|
lf.m.Lock()
|
|
|
|
defer lf.m.Unlock()
|
|
|
|
|
2017-09-11 18:55:05 +00:00
|
|
|
c := lf.optValidator[name]
|
2015-07-01 00:40:13 +00:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
var factory = &logdriverFactory{registry: make(map[string]Creator), optValidator: make(map[string]LogOptValidator)} // global factory instance
|
2015-04-09 04:23:30 +00:00
|
|
|
|
|
|
|
// RegisterLogDriver registers the given logging driver builder with given logging
|
|
|
|
// driver name.
|
|
|
|
func RegisterLogDriver(name string, c Creator) error {
|
|
|
|
return factory.register(name, c)
|
|
|
|
}
|
|
|
|
|
2015-07-21 22:26:52 +00:00
|
|
|
// RegisterLogOptValidator registers the logging option validator with
|
|
|
|
// the given logging driver name.
|
2015-07-01 00:40:13 +00:00
|
|
|
func RegisterLogOptValidator(name string, l LogOptValidator) error {
|
|
|
|
return factory.registerLogOptValidator(name, l)
|
|
|
|
}
|
|
|
|
|
2015-04-09 04:23:30 +00:00
|
|
|
// GetLogDriver provides the logging driver builder for a logging driver name.
|
|
|
|
func GetLogDriver(name string) (Creator, error) {
|
|
|
|
return factory.get(name)
|
|
|
|
}
|
2015-07-01 00:40:13 +00:00
|
|
|
|
2016-11-23 02:55:27 +00:00
|
|
|
var builtInLogOpts = map[string]bool{
|
|
|
|
"mode": true,
|
|
|
|
"max-buffer-size": true,
|
|
|
|
}
|
|
|
|
|
2015-07-21 22:26:52 +00:00
|
|
|
// ValidateLogOpts checks the options for the given log driver. The
|
|
|
|
// options supported are specific to the LogDriver implementation.
|
2015-07-01 00:40:13 +00:00
|
|
|
func ValidateLogOpts(name string, cfg map[string]string) error {
|
2016-03-12 12:50:37 +00:00
|
|
|
if name == "none" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-11-23 02:55:27 +00:00
|
|
|
switch containertypes.LogMode(cfg["mode"]) {
|
|
|
|
case containertypes.LogModeBlocking, containertypes.LogModeNonBlock, containertypes.LogModeUnset:
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("logger: logging mode not supported: %s", cfg["mode"])
|
|
|
|
}
|
|
|
|
|
|
|
|
if s, ok := cfg["max-buffer-size"]; ok {
|
|
|
|
if containertypes.LogMode(cfg["mode"]) != containertypes.LogModeNonBlock {
|
|
|
|
return fmt.Errorf("logger: max-buffer-size option is only supported with 'mode=%s'", containertypes.LogModeNonBlock)
|
|
|
|
}
|
|
|
|
if _, err := units.RAMInBytes(s); err != nil {
|
|
|
|
return errors.Wrap(err, "error parsing option max-buffer-size")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-09 19:35:24 +00:00
|
|
|
if err := validateExternal(cfg); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-04-10 17:05:42 +00:00
|
|
|
registered, err := factory.driverRegistered(name)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !registered {
|
2016-03-12 12:50:37 +00:00
|
|
|
return fmt.Errorf("logger: no log driver named '%s' is registered", name)
|
|
|
|
}
|
|
|
|
|
2016-11-23 02:55:27 +00:00
|
|
|
filteredOpts := make(map[string]string, len(builtInLogOpts))
|
|
|
|
for k, v := range cfg {
|
|
|
|
if !builtInLogOpts[k] {
|
|
|
|
filteredOpts[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-12 12:50:37 +00:00
|
|
|
validator := factory.getLogOptValidator(name)
|
|
|
|
if validator != nil {
|
2016-11-23 02:55:27 +00:00
|
|
|
return validator(filteredOpts)
|
2015-07-01 00:40:13 +00:00
|
|
|
}
|
2015-07-24 16:00:50 +00:00
|
|
|
return nil
|
2015-07-01 00:40:13 +00:00
|
|
|
}
|