92 lines
2.0 KiB
Go
92 lines
2.0 KiB
Go
// Package logdaily 提供按天滚动的日志写入器(供 go-zero logx.SetWriter 使用)
|
|
package logdaily
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type dailyWriter struct {
|
|
mu sync.Mutex
|
|
dir string
|
|
base string
|
|
keepDays int
|
|
date string
|
|
f *os.File
|
|
}
|
|
|
|
// New 创建按天滚动的写入器:文件名 dir/base-2006-01-02.log,跨天自动切换,
|
|
// 超过 keepDays 天的旧日志在跨天时清理(keepDays<=0 表示永久保留)。
|
|
func New(dir, base string, keepDays int) io.WriteCloser {
|
|
return &dailyWriter{dir: dir, base: base, keepDays: keepDays}
|
|
}
|
|
|
|
func (w *dailyWriter) filename(date string) string {
|
|
return filepath.Join(w.dir, w.base+"-"+date+".log")
|
|
}
|
|
|
|
func (w *dailyWriter) Write(p []byte) (int, error) {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
|
|
today := time.Now().Format("2006-01-02")
|
|
if w.f == nil || today != w.date {
|
|
if w.f != nil {
|
|
_ = w.f.Close()
|
|
}
|
|
if err := os.MkdirAll(w.dir, 0o755); err != nil {
|
|
return 0, err
|
|
}
|
|
f, err := os.OpenFile(w.filename(today), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
w.f = f
|
|
w.date = today
|
|
w.cleanup()
|
|
}
|
|
return w.f.Write(p)
|
|
}
|
|
|
|
func (w *dailyWriter) Close() error {
|
|
w.mu.Lock()
|
|
defer w.mu.Unlock()
|
|
if w.f != nil {
|
|
return w.f.Close()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *dailyWriter) cleanup() {
|
|
if w.keepDays <= 0 {
|
|
return
|
|
}
|
|
entries, err := os.ReadDir(w.dir)
|
|
if err != nil {
|
|
return
|
|
}
|
|
cutoff := time.Now().AddDate(0, 0, -w.keepDays)
|
|
for _, e := range entries {
|
|
if e.IsDir() || !strings.HasPrefix(e.Name(), w.base+"-") || !strings.HasSuffix(e.Name(), ".log") {
|
|
continue
|
|
}
|
|
datePart := strings.TrimSuffix(strings.TrimPrefix(e.Name(), w.base+"-"), ".log")
|
|
t, err := time.ParseInLocation("2006-01-02", datePart, time.Local)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if t.Before(cutoff) {
|
|
_ = os.Remove(filepath.Join(w.dir, e.Name()))
|
|
}
|
|
}
|
|
}
|
|
|
|
var (
|
|
_ io.WriteCloser = (*dailyWriter)(nil)
|
|
_ io.Writer = (*dailyWriter)(nil)
|
|
)
|