cleanlog.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package main
  2. import (
  3. "os"
  4. "path/filepath"
  5. "sort"
  6. "strings"
  7. "time"
  8. "lc/common/util"
  9. )
  10. const (
  11. logRetentionDays = 7
  12. logMaxTotalSize = 100 * 1024 * 1024 // 100MB
  13. )
  14. type logFileInfo struct {
  15. name string
  16. size int64
  17. modTime time.Time
  18. }
  19. // removeLogFile 删除单个日志文件并返回释放的字节数
  20. func removeLogFile(dir string, f logFileInfo) (bool, int64) {
  21. path := filepath.Join(dir, f.name)
  22. if err := os.Remove(path); err != nil {
  23. util.GetTagLog().Warnf("sys", "CleanLogs:删除失败:%s,err=%v", f.name, err)
  24. return false, 0
  25. }
  26. return true, f.size
  27. }
  28. // CleanLogs 定时清理日志文件:保留7天,总大小不超过100MB
  29. func CleanLogs(args ...interface{}) interface{} {
  30. for {
  31. time.Sleep(1 * time.Hour)
  32. dir := util.GetPath(3) // {workdir}/log/
  33. entries, err := os.ReadDir(dir)
  34. if err != nil {
  35. util.GetTagLog().Warnf("sys", "CleanLogs:读取日志目录失败:%s", err)
  36. continue
  37. }
  38. var logFiles []logFileInfo
  39. var totalSize int64
  40. now := time.Now()
  41. for _, e := range entries {
  42. if e.IsDir() || !strings.HasSuffix(e.Name(), ".log") {
  43. continue
  44. }
  45. info, err := e.Info()
  46. if err != nil {
  47. continue
  48. }
  49. lf := logFileInfo{
  50. name: e.Name(),
  51. size: info.Size(),
  52. modTime: info.ModTime(),
  53. }
  54. logFiles = append(logFiles, lf)
  55. totalSize += lf.size
  56. }
  57. if len(logFiles) == 0 {
  58. continue
  59. }
  60. // 按修改时间升序排列(最旧的在前)
  61. sort.Slice(logFiles, func(i, j int) bool {
  62. return logFiles[i].modTime.Before(logFiles[j].modTime)
  63. })
  64. var deleted int
  65. var freed int64
  66. // Step 1: 删除超过7天的文件
  67. cutoff := now.AddDate(0, 0, -logRetentionDays)
  68. remaining := make([]logFileInfo, 0, len(logFiles))
  69. for _, f := range logFiles {
  70. if f.modTime.Before(cutoff) {
  71. if ok, sz := removeLogFile(dir, f); ok {
  72. deleted++
  73. freed += sz
  74. totalSize -= sz
  75. }
  76. } else {
  77. remaining = append(remaining, f)
  78. }
  79. }
  80. // Step 2: 若剩余总大小超过100MB,从最旧的文件开始删除(索引遍历避免切片复制)
  81. idx := 0
  82. for totalSize > logMaxTotalSize && idx < len(remaining) {
  83. if ok, sz := removeLogFile(dir, remaining[idx]); ok {
  84. deleted++
  85. freed += sz
  86. totalSize -= sz
  87. }
  88. idx++
  89. }
  90. if deleted > 0 {
  91. kept := len(remaining) - idx
  92. if kept < 0 {
  93. kept = 0
  94. }
  95. util.GetTagLog().Infof("sys", "CleanLogs:清理完成,删除%d个文件,释放%.1fKB,剩余%d个文件,总大小%.1fKB",
  96. deleted, float64(freed)/1024, kept, float64(totalSize)/1024)
  97. }
  98. }
  99. }