9 "github.com/docker/docker/pkg/pubsub"
12 // RotateFileWriter is Logger implementation for default Docker logging.
13 type RotateFileWriter struct {
14 f *os.File // store for closing
17 capacity int64 //maximum size of each file
18 currentSize int64 // current size of the latest file
19 maxFiles int //maximum number of files
20 notifyRotate *pubsub.Publisher
23 //NewRotateFileWriter creates new RotateFileWriter
24 func NewRotateFileWriter(logPath string, capacity int64, maxFiles int) (*RotateFileWriter, error) {
25 log, err := os.OpenFile(logPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640)
30 size, err := log.Seek(0, os.SEEK_END)
35 return &RotateFileWriter{
40 notifyRotate: pubsub.NewPublisher(0, 1),
44 //WriteLog write log message to File
45 func (w *RotateFileWriter) Write(message []byte) (int, error) {
49 return -1, errors.New("cannot write because the output file was closed")
51 if err := w.checkCapacityAndRotate(); err != nil {
56 n, err := w.f.Write(message)
58 w.currentSize += int64(n)
64 func (w *RotateFileWriter) checkCapacityAndRotate() error {
69 if w.currentSize >= w.capacity {
71 if err := w.f.Close(); err != nil {
74 if err := rotate(name, w.maxFiles); err != nil {
77 file, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 06400)
83 w.notifyRotate.Publish(struct{}{})
89 func rotate(name string, maxFiles int) error {
93 for i := maxFiles - 1; i > 1; i-- {
94 toPath := name + "." + strconv.Itoa(i)
95 fromPath := name + "." + strconv.Itoa(i-1)
96 if err := os.Rename(fromPath, toPath); err != nil && !os.IsNotExist(err) {
101 if err := os.Rename(name, name+".1"); err != nil && !os.IsNotExist(err) {
107 // LogPath returns the location the given writer logs to.
108 func (w *RotateFileWriter) LogPath() string {
114 // MaxFiles return maximum number of files
115 func (w *RotateFileWriter) MaxFiles() int {
119 //NotifyRotate returns the new subscriber
120 func (w *RotateFileWriter) NotifyRotate() chan interface{} {
121 return w.notifyRotate.Subscribe()
124 //NotifyRotateEvict removes the specified subscriber from receiving any more messages.
125 func (w *RotateFileWriter) NotifyRotateEvict(sub chan interface{}) {
126 w.notifyRotate.Evict(sub)
129 // Close closes underlying file and signals all readers to stop.
130 func (w *RotateFileWriter) Close() error {
136 if err := w.f.Close(); err != nil {