github.com/dpiddy/docker@v1.12.2-rc1/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 reader 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 record from some container. 30 type Message struct { 31 Line []byte 32 Source string 33 Timestamp time.Time 34 Attrs LogAttributes 35 } 36 37 // LogAttributes is used to hold the extra attributes available in the log message 38 // Primarily used for converting the map type to string and sorting. 39 type LogAttributes map[string]string 40 type byKey []string 41 42 func (s byKey) Len() int { return len(s) } 43 func (s byKey) Less(i, j int) bool { 44 keyI := strings.Split(s[i], "=") 45 keyJ := strings.Split(s[j], "=") 46 return keyI[0] < keyJ[0] 47 } 48 func (s byKey) Swap(i, j int) { 49 s[i], s[j] = s[j], s[i] 50 } 51 52 func (a LogAttributes) String() string { 53 var ss byKey 54 for k, v := range a { 55 ss = append(ss, k+"="+v) 56 } 57 sort.Sort(ss) 58 return strings.Join(ss, ",") 59 } 60 61 // Logger is the interface for docker logging drivers. 62 type Logger interface { 63 Log(*Message) error 64 Name() string 65 Close() error 66 } 67 68 // ReadConfig is the configuration passed into ReadLogs. 69 type ReadConfig struct { 70 Since time.Time 71 Tail int 72 Follow bool 73 } 74 75 // LogReader is the interface for reading log messages for loggers that support reading. 76 type LogReader interface { 77 // Read logs from underlying logging backend 78 ReadLogs(ReadConfig) *LogWatcher 79 } 80 81 // LogWatcher is used when consuming logs read from the LogReader interface. 82 type LogWatcher struct { 83 // For sending log messages to a reader. 84 Msg chan *Message 85 // For sending error messages that occur while while reading logs. 86 Err chan error 87 closeOnce sync.Once 88 closeNotifier chan struct{} 89 } 90 91 // NewLogWatcher returns a new LogWatcher. 92 func NewLogWatcher() *LogWatcher { 93 return &LogWatcher{ 94 Msg: make(chan *Message, logWatcherBufferSize), 95 Err: make(chan error, 1), 96 closeNotifier: make(chan struct{}), 97 } 98 } 99 100 // Close notifies the underlying log reader to stop. 101 func (w *LogWatcher) Close() { 102 // only close if not already closed 103 w.closeOnce.Do(func() { 104 close(w.closeNotifier) 105 }) 106 } 107 108 // WatchClose returns a channel receiver that receives notification 109 // when the watcher has been closed. This should only be called from 110 // one goroutine. 111 func (w *LogWatcher) WatchClose() <-chan struct{} { 112 return w.closeNotifier 113 }