github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/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  type Message backend.LogMessage
    53  
    54  // reset sets the message back to default values
    55  // This is used when putting a message back into the message pool.
    56  func (m *Message) reset() {
    57  	*m = Message{Line: m.Line[:0]}
    58  }
    59  
    60  // AsLogMessage returns a pointer to the message as a pointer to
    61  // backend.LogMessage, which is an identical type with a different purpose
    62  func (m *Message) AsLogMessage() *backend.LogMessage {
    63  	return (*backend.LogMessage)(m)
    64  }
    65  
    66  // Logger is the interface for docker logging drivers.
    67  type Logger interface {
    68  	Log(*Message) error
    69  	Name() string
    70  	Close() error
    71  }
    72  
    73  // SizedLogger is the interface for logging drivers that can control
    74  // the size of buffer used for their messages.
    75  type SizedLogger interface {
    76  	Logger
    77  	BufSize() int
    78  }
    79  
    80  // ReadConfig is the configuration passed into ReadLogs.
    81  type ReadConfig struct {
    82  	Since  time.Time
    83  	Until  time.Time
    84  	Tail   int
    85  	Follow bool
    86  }
    87  
    88  // LogReader is the interface for reading log messages for loggers that support reading.
    89  type LogReader interface {
    90  	// ReadLogs reads logs from underlying logging backend.
    91  	ReadLogs(ReadConfig) *LogWatcher
    92  }
    93  
    94  // LogWatcher is used when consuming logs read from the LogReader interface.
    95  type LogWatcher struct {
    96  	// For sending log messages to a reader.
    97  	Msg chan *Message
    98  	// For sending error messages that occur while reading logs.
    99  	Err          chan error
   100  	consumerOnce sync.Once
   101  	consumerGone chan struct{}
   102  }
   103  
   104  // NewLogWatcher returns a new LogWatcher.
   105  func NewLogWatcher() *LogWatcher {
   106  	return &LogWatcher{
   107  		Msg:          make(chan *Message, logWatcherBufferSize),
   108  		Err:          make(chan error, 1),
   109  		consumerGone: make(chan struct{}),
   110  	}
   111  }
   112  
   113  // ConsumerGone notifies that the logs consumer is gone.
   114  func (w *LogWatcher) ConsumerGone() {
   115  	// only close if not already closed
   116  	w.consumerOnce.Do(func() {
   117  		close(w.consumerGone)
   118  	})
   119  }
   120  
   121  // WatchConsumerGone returns a channel receiver that receives notification
   122  // when the log watcher consumer is gone.
   123  func (w *LogWatcher) WatchConsumerGone() <-chan struct{} {
   124  	return w.consumerGone
   125  }
   126  
   127  // Capability defines the list of capabilities that a driver can implement
   128  // These capabilities are not required to be a logging driver, however do
   129  // determine how a logging driver can be used
   130  type Capability struct {
   131  	// Determines if a log driver can read back logs
   132  	ReadLogs bool
   133  }