CleanupLogFiles 清理过期日志文件
(c *gin.Context)
| 266 | |
| 267 | // CleanupLogFiles 清理过期日志文件 |
| 268 | func CleanupLogFiles(c *gin.Context) { |
| 269 | mode := c.Query("mode") |
| 270 | valueStr := c.Query("value") |
| 271 | if mode != "by_count" && mode != "by_days" { |
| 272 | common.ApiErrorMsg(c, "invalid mode, must be by_count or by_days") |
| 273 | return |
| 274 | } |
| 275 | value, err := strconv.Atoi(valueStr) |
| 276 | if err != nil || value < 1 { |
| 277 | common.ApiErrorMsg(c, "invalid value, must be a positive integer") |
| 278 | return |
| 279 | } |
| 280 | if *common.LogDir == "" { |
| 281 | common.ApiErrorMsg(c, "log directory not configured") |
| 282 | return |
| 283 | } |
| 284 | |
| 285 | files, err := getLogFiles() |
| 286 | if err != nil { |
| 287 | common.ApiError(c, err) |
| 288 | return |
| 289 | } |
| 290 | |
| 291 | activeLogPath := logger.GetCurrentLogPath() |
| 292 | var toDelete []LogFileInfo |
| 293 | |
| 294 | switch mode { |
| 295 | case "by_count": |
| 296 | // files 已按名称降序(最新在前),保留前 value 个 |
| 297 | for i, f := range files { |
| 298 | if i < value { |
| 299 | continue |
| 300 | } |
| 301 | fullPath := filepath.Join(*common.LogDir, f.Name) |
| 302 | if fullPath == activeLogPath { |
| 303 | continue |
| 304 | } |
| 305 | toDelete = append(toDelete, f) |
| 306 | } |
| 307 | case "by_days": |
| 308 | cutoff := time.Now().AddDate(0, 0, -value) |
| 309 | for _, f := range files { |
| 310 | if f.ModTime.Before(cutoff) { |
| 311 | fullPath := filepath.Join(*common.LogDir, f.Name) |
| 312 | if fullPath == activeLogPath { |
| 313 | continue |
| 314 | } |
| 315 | toDelete = append(toDelete, f) |
| 316 | } |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | var deletedCount int |
| 321 | var freedBytes int64 |
| 322 | var failedFiles []string |
| 323 | for _, f := range toDelete { |
| 324 | fullPath := filepath.Join(*common.LogDir, f.Name) |
| 325 | if err := os.Remove(fullPath); err != nil { |
nothing calls this directly
no test coverage detected