reduced log rotation memory usage

This commit is contained in:
2024-09-18 17:50:14 +02:00
parent 64fbdbbbdf
commit 38da65a848
2 changed files with 29 additions and 34 deletions

View File

@@ -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
}

View File

@@ -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)