github.com/mssola/docker@v1.8.1/daemon/logger/factory.go (about)

     1  package logger
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  	"sync"
     8  	"time"
     9  )
    10  
    11  // Creator is a method that builds a logging driver instance with given context
    12  type Creator func(Context) (Logger, error)
    13  
    14  //LogOptValidator is a method that validates the log opts provided
    15  type LogOptValidator func(cfg map[string]string) error
    16  
    17  // Context provides enough information for a logging driver to do its function
    18  type Context struct {
    19  	Config              map[string]string
    20  	ContainerID         string
    21  	ContainerName       string
    22  	ContainerEntrypoint string
    23  	ContainerArgs       []string
    24  	ContainerImageID    string
    25  	ContainerImageName  string
    26  	ContainerCreated    time.Time
    27  	LogPath             string
    28  }
    29  
    30  // Hostname returns the hostname from the underlying OS
    31  func (ctx *Context) Hostname() (string, error) {
    32  	hostname, err := os.Hostname()
    33  	if err != nil {
    34  		return "", fmt.Errorf("logger: can not resolve hostname: %v", err)
    35  	}
    36  	return hostname, nil
    37  }
    38  
    39  // Command returns the command that the container being logged was started with
    40  func (ctx *Context) Command() string {
    41  	terms := []string{ctx.ContainerEntrypoint}
    42  	for _, arg := range ctx.ContainerArgs {
    43  		terms = append(terms, arg)
    44  	}
    45  	command := strings.Join(terms, " ")
    46  	return command
    47  }
    48  
    49  type logdriverFactory struct {
    50  	registry     map[string]Creator
    51  	optValidator map[string]LogOptValidator
    52  	m            sync.Mutex
    53  }
    54  
    55  func (lf *logdriverFactory) register(name string, c Creator) error {
    56  	lf.m.Lock()
    57  	defer lf.m.Unlock()
    58  
    59  	if _, ok := lf.registry[name]; ok {
    60  		return fmt.Errorf("logger: log driver named '%s' is already registered", name)
    61  	}
    62  	lf.registry[name] = c
    63  	return nil
    64  }
    65  
    66  func (lf *logdriverFactory) registerLogOptValidator(name string, l LogOptValidator) error {
    67  	lf.m.Lock()
    68  	defer lf.m.Unlock()
    69  
    70  	if _, ok := lf.optValidator[name]; ok {
    71  		return fmt.Errorf("logger: log driver named '%s' is already registered", name)
    72  	}
    73  	lf.optValidator[name] = l
    74  	return nil
    75  }
    76  
    77  func (lf *logdriverFactory) get(name string) (Creator, error) {
    78  	lf.m.Lock()
    79  	defer lf.m.Unlock()
    80  
    81  	c, ok := lf.registry[name]
    82  	if !ok {
    83  		return c, fmt.Errorf("logger: no log driver named '%s' is registered", name)
    84  	}
    85  	return c, nil
    86  }
    87  
    88  func (lf *logdriverFactory) getLogOptValidator(name string) LogOptValidator {
    89  	lf.m.Lock()
    90  	defer lf.m.Unlock()
    91  
    92  	c, _ := lf.optValidator[name]
    93  	return c
    94  }
    95  
    96  var factory = &logdriverFactory{registry: make(map[string]Creator), optValidator: make(map[string]LogOptValidator)} // global factory instance
    97  
    98  // RegisterLogDriver registers the given logging driver builder with given logging
    99  // driver name.
   100  func RegisterLogDriver(name string, c Creator) error {
   101  	return factory.register(name, c)
   102  }
   103  
   104  func RegisterLogOptValidator(name string, l LogOptValidator) error {
   105  	return factory.registerLogOptValidator(name, l)
   106  }
   107  
   108  // GetLogDriver provides the logging driver builder for a logging driver name.
   109  func GetLogDriver(name string) (Creator, error) {
   110  	return factory.get(name)
   111  }
   112  
   113  func ValidateLogOpts(name string, cfg map[string]string) error {
   114  	l := factory.getLogOptValidator(name)
   115  	if l != nil {
   116  		return l(cfg)
   117  	}
   118  	return nil
   119  }