github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/daemon/logger/logger.go (about) 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 10 import ( 11 "errors" 12 "sort" 13 "strings" 14 "sync" 15 "time" 16 17 "github.com/docker/docker/pkg/jsonlog" 18 ) 19 20 // ErrReadLogsNotSupported is returned when the logger does not support reading logs. 21 var ErrReadLogsNotSupported = errors.New("configured logging driver does not support reading") 22 23 const ( 24 // TimeFormat is the time format used for timestamps sent to log readers. 25 TimeFormat = jsonlog.RFC3339NanoFixed 26 logWatcherBufferSize = 4096 27 ) 28 29 var messagePool = &sync.Pool{New: func() interface{} { return &Message{Line: make([]byte, 0, 256)} }} 30 31 // NewMessage returns a new message from the message sync.Pool 32 func NewMessage() *Message { 33 return messagePool.Get().(*Message) 34 } 35 36 // PutMessage puts the specified message back n the message pool. 37 // The message fields are reset before putting into the pool. 38 func PutMessage(msg *Message) { 39 msg.reset() 40 messagePool.Put(msg) 41 } 42 43 // Message is datastructure that represents piece of output produced by some 44 // container. The Line member is a slice of an array whose contents can be 45 // changed after a log driver's Log() method returns. 46 // Any changes made to this struct must also be updated in the `reset` function 47 type Message struct { 48 Line []byte 49 Source string 50 Timestamp time.Time 51 Attrs LogAttributes 52 Partial bool 53 } 54 55 // reset sets the message back to default values 56 // This is used when putting a message back into the message pool. 57 // Any changes to the `Message` struct should be reflected here. 58 func (m *Message) reset() { 59 m.Line = m.Line[:0] 60 m.Source = "" 61 m.Attrs = nil 62 m.Partial = false 63 } 64 65 // LogAttributes is used to hold the extra attributes available in the log message 66 // Primarily used for converting the map type to string and sorting. 67 type LogAttributes map[string]string 68 type byKey []string 69 70 func (s byKey) Len() int { return len(s) } 71 func (s byKey) Less(i, j int) bool { 72 keyI := strings.Split(s[i], "=") 73 keyJ := strings.Split(s[j], "=") 74 return keyI[0] < keyJ[0] 75 } 76 func (s byKey) Swap(i, j int) { 77 s[i], s[j] = s[j], s[i] 78 } 79 80 func (a LogAttributes) String() string { 81 var ss byKey 82 for k, v := range a { 83 ss = append(ss, k+"="+v) 84 } 85 sort.Sort(ss) 86 return strings.Join(ss, ",") 87 } 88 89 // Logger is the interface for docker logging drivers. 90 type Logger interface { 91 Log(*Message) error 92 Name() string 93 Close() error 94 } 95 96 // ReadConfig is the configuration passed into ReadLogs. 97 type ReadConfig struct { 98 Since time.Time 99 Tail int 100 Follow bool 101 } 102 103 // LogReader is the interface for reading log messages for loggers that support reading. 104 type LogReader interface { 105 // Read logs from underlying logging backend 106 ReadLogs(ReadConfig) *LogWatcher 107 } 108 109 // LogWatcher is used when consuming logs read from the LogReader interface. 110 type LogWatcher struct { 111 // For sending log messages to a reader. 112 Msg chan *Message 113 // For sending error messages that occur while while reading logs. 114 Err chan error 115 closeOnce sync.Once 116 closeNotifier chan struct{} 117 } 118 119 // NewLogWatcher returns a new LogWatcher. 120 func NewLogWatcher() *LogWatcher { 121 return &LogWatcher{ 122 Msg: make(chan *Message, logWatcherBufferSize), 123 Err: make(chan error, 1), 124 closeNotifier: make(chan struct{}), 125 } 126 } 127 128 // Close notifies the underlying log reader to stop. 129 func (w *LogWatcher) Close() { 130 // only close if not already closed 131 w.closeOnce.Do(func() { 132 close(w.closeNotifier) 133 }) 134 } 135 136 // WatchClose returns a channel receiver that receives notification 137 // when the watcher has been closed. This should only be called from 138 // one goroutine. 139 func (w *LogWatcher) WatchClose() <-chan struct{} { 140 return w.closeNotifier 141 }