jsonfilelog.go 1.8 KB

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