Files
go-service/internal/logger/rotation.go

103 lines
1.9 KiB
Go

package logger
import (
"fmt"
"path/filepath"
"sync"
"time"
)
type RotatingLogger struct {
dataLogger *DataLogger
currentHour int
baseDir string
mu sync.Mutex
eventLogger *EventLogger
}
func NewRotatingLogger(eventLogger *EventLogger) (*RotatingLogger, error) {
// Получаем директорию для бинарных данных
dataDir, err := GetDataLogsDir()
if err != nil {
return nil, err
}
r := &RotatingLogger{
baseDir: dataDir,
eventLogger: eventLogger,
}
if err := r.rotate(); err != nil {
return nil, err
}
go r.rotationLoop()
return r, nil
}
func (r *RotatingLogger) getFilename() string {
now := time.Now()
return filepath.Join(r.baseDir, fmt.Sprintf("gpio-%04d-%02d-%02d-%02d.bin",
now.Year(), now.Month(), now.Day(), now.Hour()))
}
func (r *RotatingLogger) rotate() error {
r.mu.Lock()
defer r.mu.Unlock()
now := time.Now()
newHour := now.Hour()
// Если уже правильный час и логгер существует - ок
if r.dataLogger != nil && r.currentHour == newHour {
return nil
}
// Закрываем старый
if r.dataLogger != nil {
r.dataLogger.Close()
}
// Открываем новый
filename := r.getFilename()
dataLogger, err := NewDataLogger(filename)
if err != nil {
if r.eventLogger != nil {
r.eventLogger.Event("ROTATION_FAILED")
}
return err
}
r.dataLogger = dataLogger
r.currentHour = newHour
if r.eventLogger != nil {
r.eventLogger.Event("ROTATION_COMPLETE")
}
return nil
}
func (r *RotatingLogger) Write(s Sample) {
r.mu.Lock()
logger := r.dataLogger
r.mu.Unlock()
if logger != nil {
logger.Write(s)
}
}
func (r *RotatingLogger) rotationLoop() {
ticker := time.NewTicker(1 * time.Minute)
for range ticker.C {
r.rotate()
}
}
func (r *RotatingLogger) Close() error {
r.mu.Lock()
defer r.mu.Unlock()
if r.dataLogger != nil {
return r.dataLogger.Close()
}
return nil
}