github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/daemon/logger/adapter.go (about)

     1  package logger // import "github.com/docker/docker/daemon/logger"
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"path/filepath"
     7  	"sync"
     8  	"time"
     9  
    10  	"github.com/docker/docker/api/types/plugins/logdriver"
    11  	"github.com/docker/docker/pkg/plugingetter"
    12  	"github.com/pkg/errors"
    13  	"github.com/sirupsen/logrus"
    14  )
    15  
    16  // pluginAdapter takes a plugin and implements the Logger interface for logger
    17  // instances
    18  type pluginAdapter struct {
    19  	driverName   string
    20  	id           string
    21  	plugin       logPlugin
    22  	fifoPath     string
    23  	capabilities Capability
    24  	logInfo      Info
    25  
    26  	// synchronize access to the log stream and shared buffer
    27  	mu     sync.Mutex
    28  	enc    logdriver.LogEntryEncoder
    29  	stream io.WriteCloser
    30  	// buf is shared for each `Log()` call to reduce allocations.
    31  	// buf must be protected by mutex
    32  	buf logdriver.LogEntry
    33  }
    34  
    35  func (a *pluginAdapter) Log(msg *Message) error {
    36  	a.mu.Lock()
    37  
    38  	a.buf.Line = msg.Line
    39  	a.buf.TimeNano = msg.Timestamp.UnixNano()
    40  	a.buf.Partial = msg.Partial
    41  	a.buf.Source = msg.Source
    42  
    43  	err := a.enc.Encode(&a.buf)
    44  	a.buf.Reset()
    45  
    46  	a.mu.Unlock()
    47  
    48  	PutMessage(msg)
    49  	return err
    50  }
    51  
    52  func (a *pluginAdapter) Name() string {
    53  	return a.driverName
    54  }
    55  
    56  func (a *pluginAdapter) Close() error {
    57  	a.mu.Lock()
    58  	defer a.mu.Unlock()
    59  
    60  	if err := a.plugin.StopLogging(filepath.Join("/", "run", "docker", "logging", a.id)); err != nil {
    61  		return err
    62  	}
    63  
    64  	if err := a.stream.Close(); err != nil {
    65  		logrus.WithError(err).Error("error closing plugin fifo")
    66  	}
    67  	if err := os.Remove(a.fifoPath); err != nil && !os.IsNotExist(err) {
    68  		logrus.WithError(err).Error("error cleaning up plugin fifo")
    69  	}
    70  
    71  	// may be nil, especially for unit tests
    72  	if pluginGetter != nil {
    73  		pluginGetter.Get(a.Name(), extName, plugingetter.Release)
    74  	}
    75  	return nil
    76  }
    77  
    78  type pluginAdapterWithRead struct {
    79  	*pluginAdapter
    80  }
    81  
    82  func (a *pluginAdapterWithRead) ReadLogs(config ReadConfig) *LogWatcher {
    83  	watcher := NewLogWatcher()
    84  
    85  	go func() {
    86  		defer close(watcher.Msg)
    87  		stream, err := a.plugin.ReadLogs(a.logInfo, config)
    88  		if err != nil {
    89  			watcher.Err <- errors.Wrap(err, "error getting log reader")
    90  			return
    91  		}
    92  		defer stream.Close()
    93  
    94  		dec := logdriver.NewLogEntryDecoder(stream)
    95  		for {
    96  			select {
    97  			case <-watcher.WatchClose():
    98  				return
    99  			default:
   100  			}
   101  
   102  			var buf logdriver.LogEntry
   103  			if err := dec.Decode(&buf); err != nil {
   104  				if err == io.EOF {
   105  					return
   106  				}
   107  				select {
   108  				case watcher.Err <- errors.Wrap(err, "error decoding log message"):
   109  				case <-watcher.WatchClose():
   110  				}
   111  				return
   112  			}
   113  
   114  			msg := &Message{
   115  				Timestamp: time.Unix(0, buf.TimeNano),
   116  				Line:      buf.Line,
   117  				Source:    buf.Source,
   118  			}
   119  
   120  			// plugin should handle this, but check just in case
   121  			if !config.Since.IsZero() && msg.Timestamp.Before(config.Since) {
   122  				continue
   123  			}
   124  			if !config.Until.IsZero() && msg.Timestamp.After(config.Until) {
   125  				return
   126  			}
   127  
   128  			select {
   129  			case watcher.Msg <- msg:
   130  			case <-watcher.WatchClose():
   131  				// make sure the message we consumed is sent
   132  				watcher.Msg <- msg
   133  				return
   134  			}
   135  		}
   136  	}()
   137  
   138  	return watcher
   139  }