github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/daemon/logger/factory.go (about) 1 package logger // import "github.com/demonoid81/moby/daemon/logger" 2 3 import ( 4 "fmt" 5 "sort" 6 "sync" 7 8 containertypes "github.com/demonoid81/moby/api/types/container" 9 "github.com/demonoid81/moby/pkg/plugingetter" 10 units "github.com/docker/go-units" 11 "github.com/pkg/errors" 12 ) 13 14 // Creator builds a logging driver instance with given context. 15 type Creator func(Info) (Logger, error) 16 17 // LogOptValidator checks the options specific to the underlying 18 // logging implementation. 19 type LogOptValidator func(cfg map[string]string) error 20 21 type logdriverFactory struct { 22 registry map[string]Creator 23 optValidator map[string]LogOptValidator 24 m sync.Mutex 25 } 26 27 func (lf *logdriverFactory) list() []string { 28 ls := make([]string, 0, len(lf.registry)) 29 lf.m.Lock() 30 for name := range lf.registry { 31 ls = append(ls, name) 32 } 33 lf.m.Unlock() 34 sort.Strings(ls) 35 return ls 36 } 37 38 // ListDrivers gets the list of registered log driver names 39 func ListDrivers() []string { 40 return factory.list() 41 } 42 43 func (lf *logdriverFactory) register(name string, c Creator) error { 44 if lf.driverRegistered(name) { 45 return fmt.Errorf("logger: log driver named '%s' is already registered", name) 46 } 47 48 lf.m.Lock() 49 lf.registry[name] = c 50 lf.m.Unlock() 51 return nil 52 } 53 54 func (lf *logdriverFactory) driverRegistered(name string) bool { 55 lf.m.Lock() 56 _, ok := lf.registry[name] 57 lf.m.Unlock() 58 if !ok { 59 if pluginGetter != nil { // this can be nil when the init functions are running 60 if l, _ := getPlugin(name, plugingetter.Lookup); l != nil { 61 return true 62 } 63 } 64 } 65 return ok 66 } 67 68 func (lf *logdriverFactory) registerLogOptValidator(name string, l LogOptValidator) error { 69 lf.m.Lock() 70 defer lf.m.Unlock() 71 72 if _, ok := lf.optValidator[name]; ok { 73 return fmt.Errorf("logger: log validator named '%s' is already registered", name) 74 } 75 lf.optValidator[name] = l 76 return nil 77 } 78 79 func (lf *logdriverFactory) get(name string) (Creator, error) { 80 lf.m.Lock() 81 defer lf.m.Unlock() 82 83 c, ok := lf.registry[name] 84 if ok { 85 return c, nil 86 } 87 88 c, err := getPlugin(name, plugingetter.Acquire) 89 return c, errors.Wrapf(err, "logger: no log driver named '%s' is registered", name) 90 } 91 92 func (lf *logdriverFactory) getLogOptValidator(name string) LogOptValidator { 93 lf.m.Lock() 94 defer lf.m.Unlock() 95 96 c := lf.optValidator[name] 97 return c 98 } 99 100 var factory = &logdriverFactory{registry: make(map[string]Creator), optValidator: make(map[string]LogOptValidator)} // global factory instance 101 102 // RegisterLogDriver registers the given logging driver builder with given logging 103 // driver name. 104 func RegisterLogDriver(name string, c Creator) error { 105 return factory.register(name, c) 106 } 107 108 // RegisterLogOptValidator registers the logging option validator with 109 // the given logging driver name. 110 func RegisterLogOptValidator(name string, l LogOptValidator) error { 111 return factory.registerLogOptValidator(name, l) 112 } 113 114 // GetLogDriver provides the logging driver builder for a logging driver name. 115 func GetLogDriver(name string) (Creator, error) { 116 return factory.get(name) 117 } 118 119 var builtInLogOpts = map[string]bool{ 120 "mode": true, 121 "max-buffer-size": true, 122 } 123 124 // ValidateLogOpts checks the options for the given log driver. The 125 // options supported are specific to the LogDriver implementation. 126 func ValidateLogOpts(name string, cfg map[string]string) error { 127 if name == "none" { 128 return nil 129 } 130 131 switch containertypes.LogMode(cfg["mode"]) { 132 case containertypes.LogModeBlocking, containertypes.LogModeNonBlock, containertypes.LogModeUnset: 133 default: 134 return fmt.Errorf("logger: logging mode not supported: %s", cfg["mode"]) 135 } 136 137 if s, ok := cfg["max-buffer-size"]; ok { 138 if containertypes.LogMode(cfg["mode"]) != containertypes.LogModeNonBlock { 139 return fmt.Errorf("logger: max-buffer-size option is only supported with 'mode=%s'", containertypes.LogModeNonBlock) 140 } 141 if _, err := units.RAMInBytes(s); err != nil { 142 return errors.Wrap(err, "error parsing option max-buffer-size") 143 } 144 } 145 146 if err := validateExternal(cfg); err != nil { 147 return err 148 } 149 150 if !factory.driverRegistered(name) { 151 return fmt.Errorf("logger: no log driver named '%s' is registered", name) 152 } 153 154 filteredOpts := make(map[string]string, len(builtInLogOpts)) 155 for k, v := range cfg { 156 if !builtInLogOpts[k] { 157 filteredOpts[k] = v 158 } 159 } 160 161 validator := factory.getLogOptValidator(name) 162 if validator != nil { 163 return validator(filteredOpts) 164 } 165 return nil 166 }