| package jsonfilelog // import "github.com/docker/docker/daemon/logger/jsonfilelog" | |
| import ( | |
| "context" | |
| "encoding/json" | |
| "io" | |
| "github.com/docker/docker/api/types/backend" | |
| "github.com/docker/docker/daemon/logger" | |
| "github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog" | |
| "github.com/docker/docker/daemon/logger/loggerutils" | |
| "github.com/docker/docker/pkg/tailfile" | |
| ) | |
| var _ logger.LogReader = (*JSONFileLogger)(nil) | |
| // ReadLogs implements the logger's LogReader interface for the logs | |
| // created by this driver. | |
| func (l *JSONFileLogger) ReadLogs(ctx context.Context, config logger.ReadConfig) *logger.LogWatcher { | |
| return l.writer.ReadLogs(ctx, config) | |
| } | |
| func decodeLogLine(dec *json.Decoder, l *jsonlog.JSONLog) (*logger.Message, error) { | |
| l.Reset() | |
| if err := dec.Decode(l); err != nil { | |
| return nil, err | |
| } | |
| var attrs []backend.LogAttr | |
| if len(l.Attrs) != 0 { | |
| attrs = make([]backend.LogAttr, 0, len(l.Attrs)) | |
| for k, v := range l.Attrs { | |
| attrs = append(attrs, backend.LogAttr{Key: k, Value: v}) | |
| } | |
| } | |
| msg := &logger.Message{ | |
| Source: l.Stream, | |
| Timestamp: l.Created, | |
| Line: []byte(l.Log), | |
| Attrs: attrs, | |
| } | |
| return msg, nil | |
| } | |
| type decoder struct { | |
| rdr io.Reader | |
| dec *json.Decoder | |
| jl *jsonlog.JSONLog | |
| } | |
| func (d *decoder) Reset(rdr io.Reader) { | |
| d.rdr = rdr | |
| d.dec = nil | |
| if d.jl != nil { | |
| d.jl.Reset() | |
| } | |
| } | |
| func (d *decoder) Close() { | |
| d.dec = nil | |
| d.rdr = nil | |
| d.jl = nil | |
| } | |
| func (d *decoder) Decode() (msg *logger.Message, err error) { | |
| if d.dec == nil { | |
| d.dec = json.NewDecoder(d.rdr) | |
| } | |
| if d.jl == nil { | |
| d.jl = &jsonlog.JSONLog{} | |
| } | |
| return decodeLogLine(d.dec, d.jl) | |
| } | |
| // decodeFunc is used to create a decoder for the log file reader | |
| func decodeFunc(rdr io.Reader) loggerutils.Decoder { | |
| return &decoder{ | |
| rdr: rdr, | |
| dec: nil, | |
| jl: nil, | |
| } | |
| } | |
| func getTailReader(ctx context.Context, r loggerutils.SizeReaderAt, req int) (loggerutils.SizeReaderAt, int, error) { | |
| return tailfile.NewTailReader(ctx, r, req) | |
| } |