moby--moby/daemon/logger/jsonfilelog/jsonfilelog.go

88 lines
1.8 KiB
Go

package jsonfilelog
import (
"bytes"
"io"
"os"
"sync"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/pkg/jsonlog"
"github.com/docker/docker/pkg/timeutils"
)
const (
Name = "json-file"
)
// JSONFileLogger is Logger implementation for default docker logging:
// JSON objects to file
type JSONFileLogger struct {
buf *bytes.Buffer
f *os.File // store for closing
mu sync.Mutex // protects buffer
ctx logger.Context
}
func init() {
if err := logger.RegisterLogDriver(Name, New); err != nil {
logrus.Fatal(err)
}
}
// New creates new JSONFileLogger which writes to filename
func New(ctx logger.Context) (logger.Logger, error) {
log, err := os.OpenFile(ctx.LogPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600)
if err != nil {
return nil, err
}
return &JSONFileLogger{
f: log,
buf: bytes.NewBuffer(nil),
ctx: ctx,
}, nil
}
// Log converts logger.Message to jsonlog.JSONLog and serializes it to file
func (l *JSONFileLogger) Log(msg *logger.Message) error {
l.mu.Lock()
defer l.mu.Unlock()
timestamp, err := timeutils.FastMarshalJSON(msg.Timestamp)
if err != nil {
return err
}
err = (&jsonlog.JSONLogBytes{Log: append(msg.Line, '\n'), Stream: msg.Source, Created: timestamp}).MarshalJSONBuf(l.buf)
if err != nil {
return err
}
l.buf.WriteByte('\n')
_, err = l.buf.WriteTo(l.f)
if err != nil {
// this buffer is screwed, replace it with another to avoid races
l.buf = bytes.NewBuffer(nil)
return err
}
return nil
}
func (l *JSONFileLogger) GetReader() (io.Reader, error) {
return os.Open(l.ctx.LogPath)
}
func (l *JSONFileLogger) LogPath() string {
return l.ctx.LogPath
}
// Close closes underlying file
func (l *JSONFileLogger) Close() error {
return l.f.Close()
}
// Name returns name of this logger
func (l *JSONFileLogger) Name() string {
return Name
}