logger.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Package logger defines interfaces that logger drivers implement to
  2. // log messages.
  3. //
  4. // The other half of a logger driver is the implementation of the
  5. // factory, which holds the contextual instance information that
  6. // allows multiple loggers of the same type to perform different
  7. // actions, such as logging to different locations.
  8. package logger
  9. import (
  10. "errors"
  11. "sort"
  12. "strings"
  13. "sync"
  14. "time"
  15. "github.com/docker/docker/pkg/jsonlog"
  16. )
  17. // ErrReadLogsNotSupported is returned when the logger does not support reading logs.
  18. var ErrReadLogsNotSupported = errors.New("configured logging reader does not support reading")
  19. const (
  20. // TimeFormat is the time format used for timestamps sent to log readers.
  21. TimeFormat = jsonlog.RFC3339NanoFixed
  22. logWatcherBufferSize = 4096
  23. )
  24. // Message is datastructure that represents record from some container.
  25. type Message struct {
  26. Line []byte
  27. Source string
  28. Timestamp time.Time
  29. Attrs LogAttributes
  30. }
  31. // LogAttributes is used to hold the extra attributes available in the log message
  32. // Primarily used for converting the map type to string and sorting.
  33. type LogAttributes map[string]string
  34. type byKey []string
  35. func (s byKey) Len() int { return len(s) }
  36. func (s byKey) Less(i, j int) bool {
  37. keyI := strings.Split(s[i], "=")
  38. keyJ := strings.Split(s[j], "=")
  39. return keyI[0] < keyJ[0]
  40. }
  41. func (s byKey) Swap(i, j int) {
  42. s[i], s[j] = s[j], s[i]
  43. }
  44. func (a LogAttributes) String() string {
  45. var ss byKey
  46. for k, v := range a {
  47. ss = append(ss, k+"="+v)
  48. }
  49. sort.Sort(ss)
  50. return strings.Join(ss, ",")
  51. }
  52. // Logger is the interface for docker logging drivers.
  53. type Logger interface {
  54. Log(*Message) error
  55. Name() string
  56. Close() error
  57. }
  58. // ReadConfig is the configuration passed into ReadLogs.
  59. type ReadConfig struct {
  60. Since time.Time
  61. Tail int
  62. Follow bool
  63. }
  64. // LogReader is the interface for reading log messages for loggers that support reading.
  65. type LogReader interface {
  66. // Read logs from underlying logging backend
  67. ReadLogs(ReadConfig) *LogWatcher
  68. }
  69. // LogWatcher is used when consuming logs read from the LogReader interface.
  70. type LogWatcher struct {
  71. // For sending log messages to a reader.
  72. Msg chan *Message
  73. // For sending error messages that occur while while reading logs.
  74. Err chan error
  75. closeOnce sync.Once
  76. closeNotifier chan struct{}
  77. }
  78. // NewLogWatcher returns a new LogWatcher.
  79. func NewLogWatcher() *LogWatcher {
  80. return &LogWatcher{
  81. Msg: make(chan *Message, logWatcherBufferSize),
  82. Err: make(chan error, 1),
  83. closeNotifier: make(chan struct{}),
  84. }
  85. }
  86. // Close notifies the underlying log reader to stop.
  87. func (w *LogWatcher) Close() {
  88. // only close if not already closed
  89. w.closeOnce.Do(func() {
  90. close(w.closeNotifier)
  91. })
  92. }
  93. // WatchClose returns a channel receiver that receives notification
  94. // when the watcher has been closed. This should only be called from
  95. // one goroutine.
  96. func (w *LogWatcher) WatchClose() <-chan struct{} {
  97. return w.closeNotifier
  98. }