diff --git a/server/config.yaml b/server/config.yaml index 89fed46f31..6f113138f9 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -16,6 +16,7 @@ zap: encode-level: LowercaseColorLevelEncoder stacktrace-key: stacktrace log-in-console: true + retention-day: -1 # redis configuration redis: diff --git a/server/config/zap.go b/server/config/zap.go index 3b51c4ef55..0e8ae2b293 100644 --- a/server/config/zap.go +++ b/server/config/zap.go @@ -14,6 +14,7 @@ type Zap struct { StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"` // 栈名 ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"` // 显示行 LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台 + RetentionDay int `mapstructure:"retention-day" json:"retention-day" yaml:"retention-day"` // 日志保留天数 } // Levels 根据字符串转化为 zapcore.Levels diff --git a/server/core/internal/cutter.go b/server/core/internal/cutter.go index e4d9ee5c7e..e053af6e5d 100644 --- a/server/core/internal/cutter.go +++ b/server/core/internal/cutter.go @@ -10,12 +10,13 @@ import ( // Cutter 实现 io.Writer 接口 // 用于日志切割, strings.Join([]string{director,layout, formats..., level+".log"}, os.PathSeparator) type Cutter struct { - level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal) - layout string // 时间格式 2006-01-02 15:04:05 - formats []string // 自定义参数([]string{Director,"2006-01-02", "business"(此参数可不写), level+".log"} - director string // 日志文件夹 - file *os.File // 文件句柄 - mutex *sync.RWMutex // 读写锁 + level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal) + layout string // 时间格式 2006-01-02 15:04:05 + formats []string // 自定义参数([]string{Director,"2006-01-02", "business"(此参数可不写), level+".log"} + director string // 日志文件夹 + retentionDay int //日志保留天数 + file *os.File // 文件句柄 + mutex *sync.RWMutex // 读写锁 } type CutterOption func(*Cutter) @@ -36,11 +37,12 @@ func CutterWithFormats(format ...string) CutterOption { } } -func NewCutter(director string, level string, options ...CutterOption) *Cutter { +func NewCutter(director string, level string, retentionDay int, options ...CutterOption) *Cutter { rotate := &Cutter{ - level: level, - director: director, - mutex: new(sync.RWMutex), + level: level, + director: director, + retentionDay: retentionDay, + mutex: new(sync.RWMutex), } for i := 0; i < len(options); i++ { options[i](rotate) @@ -77,6 +79,10 @@ func (c *Cutter) Write(bytes []byte) (n int, err error) { if err != nil { return 0, err } + err = removeNDaysFolders(c.director, c.retentionDay) + if err != nil { + return 0, err + } c.file, err = os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) if err != nil { return 0, err @@ -93,3 +99,23 @@ func (c *Cutter) Sync() error { } return nil } + +// 增加日志目录文件清理 小于等于零的值默认忽略不再处理 +func removeNDaysFolders(dir string, days int) error { + if days <= 0 { + return nil + } + cutoff := time.Now().AddDate(0, 0, -days) + return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() && info.ModTime().Before(cutoff) && path != dir { + err = os.RemoveAll(path) + if err != nil { + return err + } + } + return nil + }) +} diff --git a/server/core/internal/zap_core.go b/server/core/internal/zap_core.go index 4ab9716637..4648e60cba 100644 --- a/server/core/internal/zap_core.go +++ b/server/core/internal/zap_core.go @@ -27,6 +27,7 @@ func (z *ZapCore) WriteSyncer(formats ...string) zapcore.WriteSyncer { cutter := NewCutter( global.GVA_CONFIG.Zap.Director, z.level.String(), + global.GVA_CONFIG.Zap.RetentionDay, CutterWithLayout(time.DateOnly), CutterWithFormats(formats...), )