github.com/sams1990/dockerrepo@v17.12.1-ce-rc2+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
     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 datastructure 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.Partial = false
    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 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  }
   135  
   136  // Capability defines the list of capabilties that a driver can implement
   137  // These capabilities are not required to be a logging driver, however do
   138  // determine how a logging driver can be used
   139  type Capability struct {
   140  	// Determines if a log driver can read back logs
   141  	ReadLogs bool
   142  }
   143  
   144  // MarshalFunc is a func that marshals a message into an arbitrary format
   145  type MarshalFunc func(*Message) ([]byte, error)