github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/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 // import "github.com/docker/docker/daemon/logger" 9 10 import ( 11 "sync" 12 "time" 13 14 "github.com/docker/docker/api/types/backend" 15 ) 16 17 // ErrReadLogsNotSupported is returned when the underlying log driver does not support reading 18 type ErrReadLogsNotSupported struct{} 19 20 func (ErrReadLogsNotSupported) Error() string { 21 return "configured logging driver does not support reading" 22 } 23 24 // NotImplemented makes this error implement the `NotImplemented` interface from api/errdefs 25 func (ErrReadLogsNotSupported) NotImplemented() {} 26 27 const ( 28 logWatcherBufferSize = 4096 29 ) 30 31 var messagePool = &sync.Pool{New: func() interface{} { return &Message{Line: make([]byte, 0, 256)} }} 32 33 // NewMessage returns a new message from the message sync.Pool 34 func NewMessage() *Message { 35 return messagePool.Get().(*Message) 36 } 37 38 // PutMessage puts the specified message back n the message pool. 39 // The message fields are reset before putting into the pool. 40 func PutMessage(msg *Message) { 41 msg.reset() 42 messagePool.Put(msg) 43 } 44 45 // Message is data structure that represents piece of output produced by some 46 // container. The Line member is a slice of an array whose contents can be 47 // changed after a log driver's Log() method returns. 48 // 49 // Message is subtyped from backend.LogMessage because there is a lot of 50 // internal complexity around the Message type that should not be exposed 51 // to any package not explicitly importing the logger type. 52 // 53 // Any changes made to this struct must also be updated in the `reset` function 54 type Message backend.LogMessage 55 56 // reset sets the message back to default values 57 // This is used when putting a message back into the message pool. 58 // Any changes to the `Message` struct should be reflected here. 59 func (m *Message) reset() { 60 m.Line = m.Line[:0] 61 m.Source = "" 62 m.Attrs = nil 63 m.PLogMetaData = nil 64 65 m.Err = nil 66 } 67 68 // AsLogMessage returns a pointer to the message as a pointer to 69 // backend.LogMessage, which is an identical type with a different purpose 70 func (m *Message) AsLogMessage() *backend.LogMessage { 71 return (*backend.LogMessage)(m) 72 } 73 74 // Logger is the interface for docker logging drivers. 75 type Logger interface { 76 Log(*Message) error 77 Name() string 78 Close() error 79 } 80 81 // SizedLogger is the interface for logging drivers that can control 82 // the size of buffer used for their messages. 83 type SizedLogger interface { 84 Logger 85 BufSize() int 86 } 87 88 // ReadConfig is the configuration passed into ReadLogs. 89 type ReadConfig struct { 90 Since time.Time 91 Until 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 reading logs. 107 Err chan error 108 producerOnce sync.Once 109 producerGone chan struct{} 110 consumerOnce sync.Once 111 consumerGone chan struct{} 112 } 113 114 // NewLogWatcher returns a new LogWatcher. 115 func NewLogWatcher() *LogWatcher { 116 return &LogWatcher{ 117 Msg: make(chan *Message, logWatcherBufferSize), 118 Err: make(chan error, 1), 119 producerGone: make(chan struct{}), 120 consumerGone: make(chan struct{}), 121 } 122 } 123 124 // ProducerGone notifies the underlying log reader that 125 // the logs producer (a container) is gone. 126 func (w *LogWatcher) ProducerGone() { 127 // only close if not already closed 128 w.producerOnce.Do(func() { 129 close(w.producerGone) 130 }) 131 } 132 133 // WatchProducerGone returns a channel receiver that receives notification 134 // once the logs producer (a container) is gone. 135 func (w *LogWatcher) WatchProducerGone() <-chan struct{} { 136 return w.producerGone 137 } 138 139 // ConsumerGone notifies that the logs consumer is gone. 140 func (w *LogWatcher) ConsumerGone() { 141 // only close if not already closed 142 w.consumerOnce.Do(func() { 143 close(w.consumerGone) 144 }) 145 } 146 147 // WatchConsumerGone returns a channel receiver that receives notification 148 // when the log watcher consumer is gone. 149 func (w *LogWatcher) WatchConsumerGone() <-chan struct{} { 150 return w.consumerGone 151 } 152 153 // Capability defines the list of capabilities that a driver can implement 154 // These capabilities are not required to be a logging driver, however do 155 // determine how a logging driver can be used 156 type Capability struct { 157 // Determines if a log driver can read back logs 158 ReadLogs bool 159 } 160 161 // MarshalFunc is a func that marshals a message into an arbitrary format 162 type MarshalFunc func(*Message) ([]byte, error)