mirror of
https://github.com/eosswedenorg/thalos
synced 2026-07-04 12:03:41 +02:00
Adding app/log/RotatingFile.go
This commit is contained in:
parent
de266da33c
commit
e44dc2f4f1
1 changed files with 114 additions and 0 deletions
114
app/log/RotatingFile.go
Normal file
114
app/log/RotatingFile.go
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RotatingFile struct {
|
||||||
|
fd *os.File
|
||||||
|
size int64
|
||||||
|
maxSize int64
|
||||||
|
ts time.Time
|
||||||
|
maxAge time.Duration
|
||||||
|
format string
|
||||||
|
}
|
||||||
|
|
||||||
|
func open(filename string) (*os.File, error) {
|
||||||
|
return os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0o666)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRotatingFile(filename string, maxSize int64, maxAge time.Duration) (*RotatingFile, error) {
|
||||||
|
if err := os.MkdirAll(path.Dir(filename), 0o766); err != nil && !os.IsExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := fd.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &RotatingFile{
|
||||||
|
fd: fd,
|
||||||
|
size: stat.Size(),
|
||||||
|
maxSize: maxSize,
|
||||||
|
ts: time.Now(),
|
||||||
|
maxAge: maxAge,
|
||||||
|
format: "2006-01-02_150405",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRotatingFileFromConfig(config Config) (*RotatingFile, error) {
|
||||||
|
return NewRotatingFile(config.GetFilePath(), int64(config.MaxFileSize), config.MaxTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *RotatingFile) newFilename(name string) string {
|
||||||
|
ext := path.Ext(name)
|
||||||
|
if len(ext) > 0 {
|
||||||
|
name = name[:len(name)-len(ext)]
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s-%s%s", name, time.Now().Format(w.format), ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate the file.
|
||||||
|
func (w *RotatingFile) Rotate() error {
|
||||||
|
dst, err := os.OpenFile(w.newFilename(w.fd.Name()), os.O_CREATE|os.O_WRONLY, 0o666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer dst.Close()
|
||||||
|
|
||||||
|
// Seek to the beginning of file
|
||||||
|
if _, err = w.fd.Seek(0, io.SeekStart); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// And copy the contents to the new file.
|
||||||
|
if _, err = io.Copy(dst, w.fd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then truncate the log.
|
||||||
|
if err = w.fd.Truncate(0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
w.size = 0
|
||||||
|
w.ts = time.Now()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement io.Writer interface
|
||||||
|
func (w *RotatingFile) Write(p []byte) (int, error) {
|
||||||
|
n, err := w.fd.Write(p)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
w.size += int64(n)
|
||||||
|
|
||||||
|
// Check if we should rotate
|
||||||
|
if w.size >= w.maxSize || time.Since(w.ts) >= w.maxAge {
|
||||||
|
if err := w.Rotate(); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement io.Closer interface
|
||||||
|
func (w *RotatingFile) Close() error {
|
||||||
|
err := w.fd.Close()
|
||||||
|
w.fd = nil
|
||||||
|
return err
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue