103 lines
1.9 KiB
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
|
|
} |