monitoring.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package vacuum
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. // VacuumMetrics contains vacuum-specific monitoring data
  7. type VacuumMetrics struct {
  8. // Execution metrics
  9. VolumesVacuumed int64 `json:"volumes_vacuumed"`
  10. TotalSpaceReclaimed int64 `json:"total_space_reclaimed"`
  11. TotalFilesProcessed int64 `json:"total_files_processed"`
  12. TotalGarbageCollected int64 `json:"total_garbage_collected"`
  13. LastVacuumTime time.Time `json:"last_vacuum_time"`
  14. // Performance metrics
  15. AverageVacuumTime int64 `json:"average_vacuum_time_seconds"`
  16. AverageGarbageRatio float64 `json:"average_garbage_ratio"`
  17. SuccessfulOperations int64 `json:"successful_operations"`
  18. FailedOperations int64 `json:"failed_operations"`
  19. // Current task metrics
  20. CurrentGarbageRatio float64 `json:"current_garbage_ratio"`
  21. VolumesPendingVacuum int `json:"volumes_pending_vacuum"`
  22. mutex sync.RWMutex
  23. }
  24. // NewVacuumMetrics creates a new vacuum metrics instance
  25. func NewVacuumMetrics() *VacuumMetrics {
  26. return &VacuumMetrics{
  27. LastVacuumTime: time.Now(),
  28. }
  29. }
  30. // RecordVolumeVacuumed records a successful volume vacuum operation
  31. func (m *VacuumMetrics) RecordVolumeVacuumed(spaceReclaimed int64, filesProcessed int64, garbageCollected int64, vacuumTime time.Duration, garbageRatio float64) {
  32. m.mutex.Lock()
  33. defer m.mutex.Unlock()
  34. m.VolumesVacuumed++
  35. m.TotalSpaceReclaimed += spaceReclaimed
  36. m.TotalFilesProcessed += filesProcessed
  37. m.TotalGarbageCollected += garbageCollected
  38. m.SuccessfulOperations++
  39. m.LastVacuumTime = time.Now()
  40. // Update average vacuum time
  41. if m.AverageVacuumTime == 0 {
  42. m.AverageVacuumTime = int64(vacuumTime.Seconds())
  43. } else {
  44. // Exponential moving average
  45. newTime := int64(vacuumTime.Seconds())
  46. m.AverageVacuumTime = (m.AverageVacuumTime*4 + newTime) / 5
  47. }
  48. // Update average garbage ratio
  49. if m.AverageGarbageRatio == 0 {
  50. m.AverageGarbageRatio = garbageRatio
  51. } else {
  52. // Exponential moving average
  53. m.AverageGarbageRatio = 0.8*m.AverageGarbageRatio + 0.2*garbageRatio
  54. }
  55. }
  56. // RecordFailure records a failed vacuum operation
  57. func (m *VacuumMetrics) RecordFailure() {
  58. m.mutex.Lock()
  59. defer m.mutex.Unlock()
  60. m.FailedOperations++
  61. }
  62. // UpdateCurrentGarbageRatio updates the current volume's garbage ratio
  63. func (m *VacuumMetrics) UpdateCurrentGarbageRatio(ratio float64) {
  64. m.mutex.Lock()
  65. defer m.mutex.Unlock()
  66. m.CurrentGarbageRatio = ratio
  67. }
  68. // SetVolumesPendingVacuum sets the number of volumes pending vacuum
  69. func (m *VacuumMetrics) SetVolumesPendingVacuum(count int) {
  70. m.mutex.Lock()
  71. defer m.mutex.Unlock()
  72. m.VolumesPendingVacuum = count
  73. }
  74. // GetMetrics returns a copy of the current metrics (without the mutex)
  75. func (m *VacuumMetrics) GetMetrics() VacuumMetrics {
  76. m.mutex.RLock()
  77. defer m.mutex.RUnlock()
  78. // Create a copy without the mutex to avoid copying lock value
  79. return VacuumMetrics{
  80. VolumesVacuumed: m.VolumesVacuumed,
  81. TotalSpaceReclaimed: m.TotalSpaceReclaimed,
  82. TotalFilesProcessed: m.TotalFilesProcessed,
  83. TotalGarbageCollected: m.TotalGarbageCollected,
  84. LastVacuumTime: m.LastVacuumTime,
  85. AverageVacuumTime: m.AverageVacuumTime,
  86. AverageGarbageRatio: m.AverageGarbageRatio,
  87. SuccessfulOperations: m.SuccessfulOperations,
  88. FailedOperations: m.FailedOperations,
  89. CurrentGarbageRatio: m.CurrentGarbageRatio,
  90. VolumesPendingVacuum: m.VolumesPendingVacuum,
  91. }
  92. }
  93. // GetSuccessRate returns the success rate as a percentage
  94. func (m *VacuumMetrics) GetSuccessRate() float64 {
  95. m.mutex.RLock()
  96. defer m.mutex.RUnlock()
  97. total := m.SuccessfulOperations + m.FailedOperations
  98. if total == 0 {
  99. return 100.0
  100. }
  101. return float64(m.SuccessfulOperations) / float64(total) * 100.0
  102. }
  103. // GetAverageSpaceReclaimed returns the average space reclaimed per volume
  104. func (m *VacuumMetrics) GetAverageSpaceReclaimed() float64 {
  105. m.mutex.RLock()
  106. defer m.mutex.RUnlock()
  107. if m.VolumesVacuumed == 0 {
  108. return 0
  109. }
  110. return float64(m.TotalSpaceReclaimed) / float64(m.VolumesVacuumed)
  111. }
  112. // Reset resets all metrics to zero
  113. func (m *VacuumMetrics) Reset() {
  114. m.mutex.Lock()
  115. defer m.mutex.Unlock()
  116. *m = VacuumMetrics{
  117. LastVacuumTime: time.Now(),
  118. }
  119. }
  120. // Global metrics instance for vacuum tasks
  121. var globalVacuumMetrics = NewVacuumMetrics()
  122. // GetGlobalVacuumMetrics returns the global vacuum metrics instance
  123. func GetGlobalVacuumMetrics() *VacuumMetrics {
  124. return globalVacuumMetrics
  125. }