reduced log rotation memory usage
This commit is contained in:
@@ -3,21 +3,23 @@ package logging
|
|||||||
import (
|
import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"io"
|
"io"
|
||||||
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
File base logger with log-rotate capabilities.
|
implements io.Writer interface
|
||||||
The rotate process must be initiated from an external goroutine.
|
|
||||||
|
|
||||||
After rotation the previous logs file are compressed with gzip algorithm.
|
File base logger with log-rotate capabilities.
|
||||||
|
The rotate process must be initiated from an external goroutine.
|
||||||
|
|
||||||
The rotated log follows this naming: [filename].UTC time.gz
|
After rotation the previous logs file are compressed with gzip algorithm.
|
||||||
|
|
||||||
|
The rotated log follows this naming: [filename].UTC time.gz
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// implements io.Writer interface
|
|
||||||
type LogRotateWriter struct {
|
type LogRotateWriter struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
fd *os.File
|
fd *os.File
|
||||||
@@ -40,50 +42,41 @@ func (w *LogRotateWriter) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *LogRotateWriter) Rotate() error {
|
func (w *LogRotateWriter) Rotate() error {
|
||||||
var err error
|
slog.Info("started log rotation")
|
||||||
|
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
|
|
||||||
gzFile, err := os.Create(w.filename + "." + time.Now().Format(time.RFC3339) + ".gz")
|
gzFile, err := os.Create(strings.TrimSuffix(w.filename, ".log") + "-" + time.Now().Format(time.RFC3339) + ".log.gz")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := io.ReadAll(w.fd)
|
zw := gzip.NewWriter(gzFile)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
w.mu.Unlock()
|
zw.Close()
|
||||||
w.gzipLog(gzFile, &data)
|
zw.Flush()
|
||||||
|
gzFile.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
_, err = os.Stat(w.filename)
|
if _, err := os.Stat(w.filename); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.fd != nil {
|
fd, _ := os.Open(w.filename)
|
||||||
err = w.fd.Close()
|
io.Copy(zw, fd)
|
||||||
w.fd = nil
|
fd.Close()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Remove(w.filename)
|
w.fd.Close()
|
||||||
if err != nil {
|
|
||||||
|
if err := os.Remove(w.filename); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.fd, err = os.Create(w.filename)
|
w.fd, _ = os.Create(w.filename)
|
||||||
|
|
||||||
|
w.mu.Unlock()
|
||||||
|
slog.Info("ended log rotation")
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LogRotateWriter) gzipLog(wr io.Writer, data *[]byte) error {
|
|
||||||
if _, err := gzip.NewWriter(wr).Write(*data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ func RunBlocking(rc *RunConfig) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer logger.Rotate()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Hour * 24)
|
time.Sleep(time.Hour * 24)
|
||||||
|
|||||||
Reference in New Issue
Block a user