package logging import ( "os" "path/filepath" "sync" "time" ) // DailyWriter writes log entries to //. It keeps the // file handle open for the active day and rotates on the first write after // midnight, matching the directory layout consumed by the log viewer. type DailyWriter struct { mu sync.Mutex root string name string date string file *os.File } func NewDailyWriter(root, name string) *DailyWriter { return &DailyWriter{root: root, name: name} } func (w *DailyWriter) Write(value []byte) (int, error) { w.mu.Lock() defer w.mu.Unlock() date := time.Now().Format("2006-01-02") if w.file == nil || w.date != date { if w.file != nil { _ = w.file.Close() } directory := filepath.Join(w.root, date) if err := os.MkdirAll(directory, 0o755); err != nil { return 0, err } file, err := os.OpenFile(filepath.Join(directory, w.name), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644) if err != nil { return 0, err } w.file, w.date = file, date } return w.file.Write(value) } func (w *DailyWriter) Close() error { w.mu.Lock() defer w.mu.Unlock() if w.file == nil { return nil } err := w.file.Close() w.file = nil return err }