2
0

loglimit_hook.go 2.1 KB

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