| package logger |
| |
| import ( |
| "fmt" |
| "os" |
| "strings" |
| "sync" |
| "time" |
| ) |
| |
| // Creator is a method that builds a logging driver instance with given context |
| type Creator func(Context) (Logger, error) |
| |
| //LogOptValidator is a method that validates the log opts provided |
| type LogOptValidator func(cfg map[string]string) error |
| |
| // Context provides enough information for a logging driver to do its function |
| type Context struct { |
| Config map[string]string |
| ContainerID string |
| ContainerName string |
| ContainerEntrypoint string |
| ContainerArgs []string |
| ContainerImageID string |
| ContainerImageName string |
| ContainerCreated time.Time |
| LogPath string |
| } |
| |
| // Hostname returns the hostname from the underlying OS |
| func (ctx *Context) Hostname() (string, error) { |
| hostname, err := os.Hostname() |
| if err != nil { |
| return "", fmt.Errorf("logger: can not resolve hostname: %v", err) |
| } |
| return hostname, nil |
| } |
| |
| // Command returns the command that the container being logged was started with |
| func (ctx *Context) Command() string { |
| terms := []string{ctx.ContainerEntrypoint} |
| for _, arg := range ctx.ContainerArgs { |
| terms = append(terms, arg) |
| } |
| command := strings.Join(terms, " ") |
| return command |
| } |
| |
| type logdriverFactory struct { |
| registry map[string]Creator |
| optValidator map[string]LogOptValidator |
| m sync.Mutex |
| } |
| |
| func (lf *logdriverFactory) register(name string, c Creator) error { |
| lf.m.Lock() |
| defer lf.m.Unlock() |
| |
| if _, ok := lf.registry[name]; ok { |
| return fmt.Errorf("logger: log driver named '%s' is already registered", name) |
| } |
| lf.registry[name] = c |
| return nil |
| } |
| |
| func (lf *logdriverFactory) registerLogOptValidator(name string, l LogOptValidator) error { |
| lf.m.Lock() |
| defer lf.m.Unlock() |
| |
| if _, ok := lf.optValidator[name]; ok { |
| return fmt.Errorf("logger: log driver named '%s' is already registered", name) |
| } |
| lf.optValidator[name] = l |
| return nil |
| } |
| |
| func (lf *logdriverFactory) get(name string) (Creator, error) { |
| lf.m.Lock() |
| defer lf.m.Unlock() |
| |
| c, ok := lf.registry[name] |
| if !ok { |
| return c, fmt.Errorf("logger: no log driver named '%s' is registered", name) |
| } |
| return c, nil |
| } |
| |
| func (lf *logdriverFactory) getLogOptValidator(name string) LogOptValidator { |
| lf.m.Lock() |
| defer lf.m.Unlock() |
| |
| c, _ := lf.optValidator[name] |
| return c |
| } |
| |
| var factory = &logdriverFactory{registry: make(map[string]Creator), optValidator: make(map[string]LogOptValidator)} // global factory instance |
| |
| // RegisterLogDriver registers the given logging driver builder with given logging |
| // driver name. |
| func RegisterLogDriver(name string, c Creator) error { |
| return factory.register(name, c) |
| } |
| |
| func RegisterLogOptValidator(name string, l LogOptValidator) error { |
| return factory.registerLogOptValidator(name, l) |
| } |
| |
| // GetLogDriver provides the logging driver builder for a logging driver name. |
| func GetLogDriver(name string) (Creator, error) { |
| return factory.get(name) |
| } |
| |
| func ValidateLogOpts(name string, cfg map[string]string) error { |
| l := factory.getLogOptValidator(name) |
| if l != nil { |
| return l(cfg) |
| } |
| return nil |
| } |