github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/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)