|
@@ -1,12 +1,13 @@
|
|
package loggerutils
|
|
package loggerutils
|
|
|
|
|
|
import (
|
|
import (
|
|
- "errors"
|
|
|
|
"os"
|
|
"os"
|
|
"strconv"
|
|
"strconv"
|
|
"sync"
|
|
"sync"
|
|
|
|
|
|
|
|
+ "github.com/docker/docker/daemon/logger"
|
|
"github.com/docker/docker/pkg/pubsub"
|
|
"github.com/docker/docker/pkg/pubsub"
|
|
|
|
+ "github.com/pkg/errors"
|
|
)
|
|
)
|
|
|
|
|
|
// RotateFileWriter is Logger implementation for default Docker logging.
|
|
// RotateFileWriter is Logger implementation for default Docker logging.
|
|
@@ -18,10 +19,11 @@ type RotateFileWriter struct {
|
|
currentSize int64 // current size of the latest file
|
|
currentSize int64 // current size of the latest file
|
|
maxFiles int //maximum number of files
|
|
maxFiles int //maximum number of files
|
|
notifyRotate *pubsub.Publisher
|
|
notifyRotate *pubsub.Publisher
|
|
|
|
+ marshal logger.MarshalFunc
|
|
}
|
|
}
|
|
|
|
|
|
//NewRotateFileWriter creates new RotateFileWriter
|
|
//NewRotateFileWriter creates new RotateFileWriter
|
|
-func NewRotateFileWriter(logPath string, capacity int64, maxFiles int) (*RotateFileWriter, error) {
|
|
|
|
|
|
+func NewRotateFileWriter(logPath string, capacity int64, maxFiles int, marshaller logger.MarshalFunc) (*RotateFileWriter, error) {
|
|
log, err := os.OpenFile(logPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640)
|
|
log, err := os.OpenFile(logPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
@@ -38,27 +40,37 @@ func NewRotateFileWriter(logPath string, capacity int64, maxFiles int) (*RotateF
|
|
currentSize: size,
|
|
currentSize: size,
|
|
maxFiles: maxFiles,
|
|
maxFiles: maxFiles,
|
|
notifyRotate: pubsub.NewPublisher(0, 1),
|
|
notifyRotate: pubsub.NewPublisher(0, 1),
|
|
|
|
+ marshal: marshaller,
|
|
}, nil
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
|
|
-//WriteLog write log message to File
|
|
|
|
-func (w *RotateFileWriter) Write(message []byte) (int, error) {
|
|
|
|
|
|
+// WriteLogEntry writes the provided log message to the current log file.
|
|
|
|
+// This may trigger a rotation event if the max file/capacity limits are hit.
|
|
|
|
+func (w *RotateFileWriter) WriteLogEntry(msg *logger.Message) error {
|
|
|
|
+ b, err := w.marshal(msg)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return errors.Wrap(err, "error marshalling log message")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ logger.PutMessage(msg)
|
|
|
|
+
|
|
w.mu.Lock()
|
|
w.mu.Lock()
|
|
if w.closed {
|
|
if w.closed {
|
|
w.mu.Unlock()
|
|
w.mu.Unlock()
|
|
- return -1, errors.New("cannot write because the output file was closed")
|
|
|
|
|
|
+ return errors.New("cannot write because the output file was closed")
|
|
}
|
|
}
|
|
|
|
+
|
|
if err := w.checkCapacityAndRotate(); err != nil {
|
|
if err := w.checkCapacityAndRotate(); err != nil {
|
|
w.mu.Unlock()
|
|
w.mu.Unlock()
|
|
- return -1, err
|
|
|
|
|
|
+ return err
|
|
}
|
|
}
|
|
|
|
|
|
- n, err := w.f.Write(message)
|
|
|
|
|
|
+ n, err := w.f.Write(b)
|
|
if err == nil {
|
|
if err == nil {
|
|
w.currentSize += int64(n)
|
|
w.currentSize += int64(n)
|
|
}
|
|
}
|
|
w.mu.Unlock()
|
|
w.mu.Unlock()
|
|
- return n, err
|
|
|
|
|
|
+ return err
|
|
}
|
|
}
|
|
|
|
|
|
func (w *RotateFileWriter) checkCapacityAndRotate() error {
|
|
func (w *RotateFileWriter) checkCapacityAndRotate() error {
|
|
@@ -69,7 +81,7 @@ func (w *RotateFileWriter) checkCapacityAndRotate() error {
|
|
if w.currentSize >= w.capacity {
|
|
if w.currentSize >= w.capacity {
|
|
name := w.f.Name()
|
|
name := w.f.Name()
|
|
if err := w.f.Close(); err != nil {
|
|
if err := w.f.Close(); err != nil {
|
|
- return err
|
|
|
|
|
|
+ return errors.Wrap(err, "error closing file")
|
|
}
|
|
}
|
|
if err := rotate(name, w.maxFiles); err != nil {
|
|
if err := rotate(name, w.maxFiles); err != nil {
|
|
return err
|
|
return err
|
|
@@ -94,12 +106,12 @@ func rotate(name string, maxFiles int) error {
|
|
toPath := name + "." + strconv.Itoa(i)
|
|
toPath := name + "." + strconv.Itoa(i)
|
|
fromPath := name + "." + strconv.Itoa(i-1)
|
|
fromPath := name + "." + strconv.Itoa(i-1)
|
|
if err := os.Rename(fromPath, toPath); err != nil && !os.IsNotExist(err) {
|
|
if err := os.Rename(fromPath, toPath); err != nil && !os.IsNotExist(err) {
|
|
- return err
|
|
|
|
|
|
+ return errors.Wrap(err, "error rotating old log entries")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if err := os.Rename(name, name+".1"); err != nil && !os.IsNotExist(err) {
|
|
if err := os.Rename(name, name+".1"); err != nil && !os.IsNotExist(err) {
|
|
- return err
|
|
|
|
|
|
+ return errors.Wrap(err, "error rotating current log")
|
|
}
|
|
}
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|