daemon/logger/logger.go
ccbe539e
 // Package logger defines interfaces that logger drivers implement to
 // log messages.
 //
 // The other half of a logger driver is the implementation of the
 // factory, which holds the contextual instance information that
 // allows multiple loggers of the same type to perform different
 // actions, such as logging to different locations.
14887e2e
 package logger
 
3a8728b4
 import (
378f0657
 	"sync"
3a8728b4
 	"time"
c0391bf5
 
1044093b
 	"github.com/docker/docker/api/types/backend"
3a8728b4
 )
 
ebcb7d6b
 // ErrReadLogsNotSupported is returned when the underlying log driver does not support reading
 type ErrReadLogsNotSupported struct{}
 
 func (ErrReadLogsNotSupported) Error() string {
 	return "configured logging driver does not support reading"
 }
 
 // NotImplemented makes this error implement the `NotImplemented` interface from api/errdefs
 func (ErrReadLogsNotSupported) NotImplemented() {}
c0391bf5
 
 const (
 	logWatcherBufferSize = 4096
 )
14887e2e
 
3f4fccb6
 var messagePool = &sync.Pool{New: func() interface{} { return &Message{Line: make([]byte, 0, 256)} }}
 
 // NewMessage returns a new message from the message sync.Pool
 func NewMessage() *Message {
 	return messagePool.Get().(*Message)
 }
 
 // PutMessage puts the specified message back n the message pool.
 // The message fields are reset before putting into the pool.
 func PutMessage(msg *Message) {
 	msg.reset()
 	messagePool.Put(msg)
 }
 
513ec738
 // Message is datastructure that represents piece of output produced by some
 // container.  The Line member is a slice of an array whose contents can be
 // changed after a log driver's Log() method returns.
1044093b
 //
 // Message is subtyped from backend.LogMessage because there is a lot of
 // internal complexity around the Message type that should not be exposed
 // to any package not explicitly importing the logger type.
 //
3f4fccb6
 // Any changes made to this struct must also be updated in the `reset` function
1044093b
 type Message backend.LogMessage
513ec738
 
3f4fccb6
 // reset sets the message back to default values
 // This is used when putting a message back into the message pool.
 // Any changes to the `Message` struct should be reflected here.
 func (m *Message) reset() {
 	m.Line = m.Line[:0]
 	m.Source = ""
 	m.Attrs = nil
 	m.Partial = false
 
1044093b
 	m.Err = nil
bd9d14a0
 }
 
1044093b
 // AsLogMessage returns a pointer to the message as a pointer to
 // backend.LogMessage, which is an identical type with a different purpose
 func (m *Message) AsLogMessage() *backend.LogMessage {
 	return (*backend.LogMessage)(m)
14887e2e
 }
 
ccbe539e
 // Logger is the interface for docker logging drivers.
14887e2e
 type Logger interface {
 	Log(*Message) error
 	Name() string
 	Close() error
9b782d3a
 }
 
e1ada0b8
 // SizedLogger is the interface for logging drivers that can control
 // the size of buffer used for their messages.
 type SizedLogger interface {
 	Logger
 	BufSize() int
 }
 
ccbe539e
 // ReadConfig is the configuration passed into ReadLogs.
c0391bf5
 type ReadConfig struct {
 	Since  time.Time
e8d9a61f
 	Until  time.Time
c0391bf5
 	Tail   int
 	Follow bool
 }
 
ccbe539e
 // LogReader is the interface for reading log messages for loggers that support reading.
c0391bf5
 type LogReader interface {
 	// Read logs from underlying logging backend
 	ReadLogs(ReadConfig) *LogWatcher
 }
 
ccbe539e
 // LogWatcher is used when consuming logs read from the LogReader interface.
c0391bf5
 type LogWatcher struct {
ccbe539e
 	// For sending log messages to a reader.
c0391bf5
 	Msg chan *Message
ccbe539e
 	// For sending error messages that occur while while reading logs.
c0391bf5
 	Err           chan error
378f0657
 	closeOnce     sync.Once
c0391bf5
 	closeNotifier chan struct{}
 }
 
 // NewLogWatcher returns a new LogWatcher.
 func NewLogWatcher() *LogWatcher {
 	return &LogWatcher{
 		Msg:           make(chan *Message, logWatcherBufferSize),
 		Err:           make(chan error, 1),
 		closeNotifier: make(chan struct{}),
 	}
 }
 
ccbe539e
 // Close notifies the underlying log reader to stop.
c0391bf5
 func (w *LogWatcher) Close() {
c57faa91
 	// only close if not already closed
378f0657
 	w.closeOnce.Do(func() {
c57faa91
 		close(w.closeNotifier)
378f0657
 	})
c0391bf5
 }
 
ccbe539e
 // WatchClose returns a channel receiver that receives notification
 // when the watcher has been closed. This should only be called from
 // one goroutine.
c0391bf5
 func (w *LogWatcher) WatchClose() <-chan struct{} {
 	return w.closeNotifier
14887e2e
 }
27bd6842
 
 // Capability defines the list of capabilties that a driver can implement
 // These capabilities are not required to be a logging driver, however do
 // determine how a logging driver can be used
 type Capability struct {
 	// Determines if a log driver can read back logs
 	ReadLogs bool
 }
52d82b4f
 
 // MarshalFunc is a func that marshals a message into an arbitrary format
 type MarshalFunc func(*Message) ([]byte, error)