factory.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package logger
  2. import (
  3. "fmt"
  4. "sync"
  5. containertypes "github.com/docker/docker/api/types/container"
  6. units "github.com/docker/go-units"
  7. "github.com/pkg/errors"
  8. )
  9. // Creator builds a logging driver instance with given context.
  10. type Creator func(Info) (Logger, error)
  11. // LogOptValidator checks the options specific to the underlying
  12. // logging implementation.
  13. type LogOptValidator func(cfg map[string]string) error
  14. type logdriverFactory struct {
  15. registry map[string]Creator
  16. optValidator map[string]LogOptValidator
  17. m sync.Mutex
  18. }
  19. func (lf *logdriverFactory) register(name string, c Creator) error {
  20. if lf.driverRegistered(name) {
  21. return fmt.Errorf("logger: log driver named '%s' is already registered", name)
  22. }
  23. lf.m.Lock()
  24. lf.registry[name] = c
  25. lf.m.Unlock()
  26. return nil
  27. }
  28. func (lf *logdriverFactory) driverRegistered(name string) bool {
  29. lf.m.Lock()
  30. _, ok := lf.registry[name]
  31. lf.m.Unlock()
  32. return ok
  33. }
  34. func (lf *logdriverFactory) registerLogOptValidator(name string, l LogOptValidator) error {
  35. lf.m.Lock()
  36. defer lf.m.Unlock()
  37. if _, ok := lf.optValidator[name]; ok {
  38. return fmt.Errorf("logger: log validator named '%s' is already registered", name)
  39. }
  40. lf.optValidator[name] = l
  41. return nil
  42. }
  43. func (lf *logdriverFactory) get(name string) (Creator, error) {
  44. lf.m.Lock()
  45. defer lf.m.Unlock()
  46. c, ok := lf.registry[name]
  47. if !ok {
  48. return c, fmt.Errorf("logger: no log driver named '%s' is registered", name)
  49. }
  50. return c, nil
  51. }
  52. func (lf *logdriverFactory) getLogOptValidator(name string) LogOptValidator {
  53. lf.m.Lock()
  54. defer lf.m.Unlock()
  55. c, _ := lf.optValidator[name]
  56. return c
  57. }
  58. var factory = &logdriverFactory{registry: make(map[string]Creator), optValidator: make(map[string]LogOptValidator)} // global factory instance
  59. // RegisterLogDriver registers the given logging driver builder with given logging
  60. // driver name.
  61. func RegisterLogDriver(name string, c Creator) error {
  62. return factory.register(name, c)
  63. }
  64. // RegisterLogOptValidator registers the logging option validator with
  65. // the given logging driver name.
  66. func RegisterLogOptValidator(name string, l LogOptValidator) error {
  67. return factory.registerLogOptValidator(name, l)
  68. }
  69. // GetLogDriver provides the logging driver builder for a logging driver name.
  70. func GetLogDriver(name string) (Creator, error) {
  71. return factory.get(name)
  72. }
  73. var builtInLogOpts = map[string]bool{
  74. "mode": true,
  75. "max-buffer-size": true,
  76. }
  77. // ValidateLogOpts checks the options for the given log driver. The
  78. // options supported are specific to the LogDriver implementation.
  79. func ValidateLogOpts(name string, cfg map[string]string) error {
  80. if name == "none" {
  81. return nil
  82. }
  83. switch containertypes.LogMode(cfg["mode"]) {
  84. case containertypes.LogModeBlocking, containertypes.LogModeNonBlock, containertypes.LogModeUnset:
  85. default:
  86. return fmt.Errorf("logger: logging mode not supported: %s", cfg["mode"])
  87. }
  88. if s, ok := cfg["max-buffer-size"]; ok {
  89. if containertypes.LogMode(cfg["mode"]) != containertypes.LogModeNonBlock {
  90. return fmt.Errorf("logger: max-buffer-size option is only supported with 'mode=%s'", containertypes.LogModeNonBlock)
  91. }
  92. if _, err := units.RAMInBytes(s); err != nil {
  93. return errors.Wrap(err, "error parsing option max-buffer-size")
  94. }
  95. }
  96. if !factory.driverRegistered(name) {
  97. return fmt.Errorf("logger: no log driver named '%s' is registered", name)
  98. }
  99. filteredOpts := make(map[string]string, len(builtInLogOpts))
  100. for k, v := range cfg {
  101. if !builtInLogOpts[k] {
  102. filteredOpts[k] = v
  103. }
  104. }
  105. validator := factory.getLogOptValidator(name)
  106. if validator != nil {
  107. return validator(filteredOpts)
  108. }
  109. return nil
  110. }