github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/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 // Message is datastructure that represents piece of output produced by some 30 // container. The Line member is a slice of an array whose contents can be 31 // changed after a log driver's Log() method returns. 32 type Message struct { 33 Line []byte 34 Source string 35 Timestamp time.Time 36 Attrs LogAttributes 37 Partial bool 38 } 39 40 // CopyMessage creates a copy of the passed-in Message which will remain 41 // unchanged if the original is changed. Log drivers which buffer Messages 42 // rather than dispatching them during their Log() method should use this 43 // function to obtain a Message whose Line member's contents won't change. 44 func CopyMessage(msg *Message) *Message { 45 m := new(Message) 46 m.Line = make([]byte, len(msg.Line)) 47 copy(m.Line, msg.Line) 48 m.Source = msg.Source 49 m.Timestamp = msg.Timestamp 50 m.Partial = msg.Partial 51 m.Attrs = make(LogAttributes) 52 for k, v := range msg.Attrs { 53 m.Attrs[k] = v 54 } 55 return m 56 } 57 58 // LogAttributes is used to hold the extra attributes available in the log message 59 // Primarily used for converting the map type to string and sorting. 60 type LogAttributes map[string]string 61 type byKey []string 62 63 func (s byKey) Len() int { return len(s) } 64 func (s byKey) Less(i, j int) bool { 65 keyI := strings.Split(s[i], "=") 66 keyJ := strings.Split(s[j], "=") 67 return keyI[0] < keyJ[0] 68 } 69 func (s byKey) Swap(i, j int) { 70 s[i], s[j] = s[j], s[i] 71 } 72 73 func (a LogAttributes) String() string { 74 var ss byKey 75 for k, v := range a { 76 ss = append(ss, k+"="+v) 77 } 78 sort.Sort(ss) 79 return strings.Join(ss, ",") 80 } 81 82 // Logger is the interface for docker logging drivers. 83 type Logger interface { 84 Log(*Message) error 85 Name() string 86 Close() error 87 } 88 89 // ReadConfig is the configuration passed into ReadLogs. 90 type ReadConfig struct { 91 Since time.Time 92 Tail int 93 Follow bool 94 } 95 96 // LogReader is the interface for reading log messages for loggers that support reading. 97 type LogReader interface { 98 // Read logs from underlying logging backend 99 ReadLogs(ReadConfig) *LogWatcher 100 } 101 102 // LogWatcher is used when consuming logs read from the LogReader interface. 103 type LogWatcher struct { 104 // For sending log messages to a reader. 105 Msg chan *Message 106 // For sending error messages that occur while while reading logs. 107 Err chan error 108 closeOnce sync.Once 109 closeNotifier chan struct{} 110 } 111 112 // NewLogWatcher returns a new LogWatcher. 113 func NewLogWatcher() *LogWatcher { 114 return &LogWatcher{ 115 Msg: make(chan *Message, logWatcherBufferSize), 116 Err: make(chan error, 1), 117 closeNotifier: make(chan struct{}), 118 } 119 } 120 121 // Close notifies the underlying log reader to stop. 122 func (w *LogWatcher) Close() { 123 // only close if not already closed 124 w.closeOnce.Do(func() { 125 close(w.closeNotifier) 126 }) 127 } 128 129 // WatchClose returns a channel receiver that receives notification 130 // when the watcher has been closed. This should only be called from 131 // one goroutine. 132 func (w *LogWatcher) WatchClose() <-chan struct{} { 133 return w.closeNotifier 134 }