2
0

loglimit_hook.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package worker
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "sort"
  8. "strings"
  9. "time"
  10. )
  11. // limit
  12. type logLimiter struct {
  13. emptyHook
  14. }
  15. func newLogLimiter(provider mirrorProvider) *logLimiter {
  16. return &logLimiter{
  17. emptyHook: emptyHook{
  18. provider: provider,
  19. },
  20. }
  21. }
  22. type fileSlice []os.FileInfo
  23. func (f fileSlice) Len() int { return len(f) }
  24. func (f fileSlice) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
  25. func (f fileSlice) Less(i, j int) bool { return f[i].ModTime().Before(f[j].ModTime()) }
  26. func (l *logLimiter) preExec() error {
  27. logger.Debugf("executing log limitter for %s", l.provider.Name())
  28. p := l.provider
  29. if p.LogFile() == "/dev/null" {
  30. return nil
  31. }
  32. logDir := p.LogDir()
  33. files, err := ioutil.ReadDir(logDir)
  34. if err != nil {
  35. if os.IsNotExist(err) {
  36. os.MkdirAll(logDir, 0755)
  37. } else {
  38. return err
  39. }
  40. }
  41. matchedFiles := []os.FileInfo{}
  42. for _, f := range files {
  43. if strings.HasPrefix(f.Name(), p.Name()) {
  44. matchedFiles = append(matchedFiles, f)
  45. }
  46. }
  47. // sort the filelist in time order
  48. // earlier modified files are sorted as larger
  49. sort.Sort(
  50. sort.Reverse(
  51. fileSlice(matchedFiles),
  52. ),
  53. )
  54. // remove old files
  55. if len(matchedFiles) > 9 {
  56. for _, f := range matchedFiles[9:] {
  57. // logger.Debug(f.Name())
  58. os.Remove(filepath.Join(logDir, f.Name()))
  59. }
  60. }
  61. logFileName := fmt.Sprintf(
  62. "%s_%s.log",
  63. p.Name(),
  64. time.Now().Format("2006-01-02_15_04"),
  65. )
  66. logFilePath := filepath.Join(
  67. logDir, logFileName,
  68. )
  69. logLink := filepath.Join(logDir, "latest")
  70. if _, err = os.Lstat(logLink); err == nil {
  71. os.Remove(logLink)
  72. }
  73. os.Symlink(logFileName, logLink)
  74. ctx := p.EnterContext()
  75. ctx.Set(_LogFileKey, logFilePath)
  76. return nil
  77. }
  78. func (l *logLimiter) postSuccess() error {
  79. l.provider.ExitContext()
  80. return nil
  81. }
  82. func (l *logLimiter) postFail() error {
  83. logFile := l.provider.LogFile()
  84. logFileFail := logFile + ".fail"
  85. logDir := l.provider.LogDir()
  86. logLink := filepath.Join(logDir, "latest")
  87. os.Rename(logFile, logFileFail)
  88. os.Remove(logLink)
  89. logFileName := filepath.Base(logFileFail)
  90. os.Symlink(logFileName, logLink)
  91. l.provider.ExitContext()
  92. return nil
  93. }