github.com/circular-dark/docker@v1.7.0/daemon/logger/jsonfilelog/jsonfilelog.go (about)

     1  package jsonfilelog
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"os"
     7  	"sync"
     8  
     9  	"github.com/Sirupsen/logrus"
    10  	"github.com/docker/docker/daemon/logger"
    11  	"github.com/docker/docker/pkg/jsonlog"
    12  	"github.com/docker/docker/pkg/timeutils"
    13  )
    14  
    15  const (
    16  	Name = "json-file"
    17  )
    18  
    19  // JSONFileLogger is Logger implementation for default docker logging:
    20  // JSON objects to file
    21  type JSONFileLogger struct {
    22  	buf *bytes.Buffer
    23  	f   *os.File   // store for closing
    24  	mu  sync.Mutex // protects buffer
    25  
    26  	ctx logger.Context
    27  }
    28  
    29  func init() {
    30  	if err := logger.RegisterLogDriver(Name, New); err != nil {
    31  		logrus.Fatal(err)
    32  	}
    33  }
    34  
    35  // New creates new JSONFileLogger which writes to filename
    36  func New(ctx logger.Context) (logger.Logger, error) {
    37  	log, err := os.OpenFile(ctx.LogPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	return &JSONFileLogger{
    42  		f:   log,
    43  		buf: bytes.NewBuffer(nil),
    44  		ctx: ctx,
    45  	}, nil
    46  }
    47  
    48  // Log converts logger.Message to jsonlog.JSONLog and serializes it to file
    49  func (l *JSONFileLogger) Log(msg *logger.Message) error {
    50  	l.mu.Lock()
    51  	defer l.mu.Unlock()
    52  
    53  	timestamp, err := timeutils.FastMarshalJSON(msg.Timestamp)
    54  	if err != nil {
    55  		return err
    56  	}
    57  	err = (&jsonlog.JSONLogBytes{Log: append(msg.Line, '\n'), Stream: msg.Source, Created: timestamp}).MarshalJSONBuf(l.buf)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	l.buf.WriteByte('\n')
    62  	_, err = l.buf.WriteTo(l.f)
    63  	if err != nil {
    64  		// this buffer is screwed, replace it with another to avoid races
    65  		l.buf = bytes.NewBuffer(nil)
    66  		return err
    67  	}
    68  	return nil
    69  }
    70  
    71  func (l *JSONFileLogger) GetReader() (io.Reader, error) {
    72  	return os.Open(l.ctx.LogPath)
    73  }
    74  
    75  func (l *JSONFileLogger) LogPath() string {
    76  	return l.ctx.LogPath
    77  }
    78  
    79  // Close closes underlying file
    80  func (l *JSONFileLogger) Close() error {
    81  	return l.f.Close()
    82  }
    83  
    84  // Name returns name of this logger
    85  func (l *JSONFileLogger) Name() string {
    86  	return Name
    87  }