You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.3 KiB
151 lines
4.3 KiB
package vacuum
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// VacuumMetrics contains vacuum-specific monitoring data
|
|
type VacuumMetrics struct {
|
|
// Execution metrics
|
|
VolumesVacuumed int64 `json:"volumes_vacuumed"`
|
|
TotalSpaceReclaimed int64 `json:"total_space_reclaimed"`
|
|
TotalFilesProcessed int64 `json:"total_files_processed"`
|
|
TotalGarbageCollected int64 `json:"total_garbage_collected"`
|
|
LastVacuumTime time.Time `json:"last_vacuum_time"`
|
|
|
|
// Performance metrics
|
|
AverageVacuumTime int64 `json:"average_vacuum_time_seconds"`
|
|
AverageGarbageRatio float64 `json:"average_garbage_ratio"`
|
|
SuccessfulOperations int64 `json:"successful_operations"`
|
|
FailedOperations int64 `json:"failed_operations"`
|
|
|
|
// Current task metrics
|
|
CurrentGarbageRatio float64 `json:"current_garbage_ratio"`
|
|
VolumesPendingVacuum int `json:"volumes_pending_vacuum"`
|
|
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// NewVacuumMetrics creates a new vacuum metrics instance
|
|
func NewVacuumMetrics() *VacuumMetrics {
|
|
return &VacuumMetrics{
|
|
LastVacuumTime: time.Now(),
|
|
}
|
|
}
|
|
|
|
// RecordVolumeVacuumed records a successful volume vacuum operation
|
|
func (m *VacuumMetrics) RecordVolumeVacuumed(spaceReclaimed int64, filesProcessed int64, garbageCollected int64, vacuumTime time.Duration, garbageRatio float64) {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
m.VolumesVacuumed++
|
|
m.TotalSpaceReclaimed += spaceReclaimed
|
|
m.TotalFilesProcessed += filesProcessed
|
|
m.TotalGarbageCollected += garbageCollected
|
|
m.SuccessfulOperations++
|
|
m.LastVacuumTime = time.Now()
|
|
|
|
// Update average vacuum time
|
|
if m.AverageVacuumTime == 0 {
|
|
m.AverageVacuumTime = int64(vacuumTime.Seconds())
|
|
} else {
|
|
// Exponential moving average
|
|
newTime := int64(vacuumTime.Seconds())
|
|
m.AverageVacuumTime = (m.AverageVacuumTime*4 + newTime) / 5
|
|
}
|
|
|
|
// Update average garbage ratio
|
|
if m.AverageGarbageRatio == 0 {
|
|
m.AverageGarbageRatio = garbageRatio
|
|
} else {
|
|
// Exponential moving average
|
|
m.AverageGarbageRatio = 0.8*m.AverageGarbageRatio + 0.2*garbageRatio
|
|
}
|
|
}
|
|
|
|
// RecordFailure records a failed vacuum operation
|
|
func (m *VacuumMetrics) RecordFailure() {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
m.FailedOperations++
|
|
}
|
|
|
|
// UpdateCurrentGarbageRatio updates the current volume's garbage ratio
|
|
func (m *VacuumMetrics) UpdateCurrentGarbageRatio(ratio float64) {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
m.CurrentGarbageRatio = ratio
|
|
}
|
|
|
|
// SetVolumesPendingVacuum sets the number of volumes pending vacuum
|
|
func (m *VacuumMetrics) SetVolumesPendingVacuum(count int) {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
m.VolumesPendingVacuum = count
|
|
}
|
|
|
|
// GetMetrics returns a copy of the current metrics (without the mutex)
|
|
func (m *VacuumMetrics) GetMetrics() VacuumMetrics {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
// Create a copy without the mutex to avoid copying lock value
|
|
return VacuumMetrics{
|
|
VolumesVacuumed: m.VolumesVacuumed,
|
|
TotalSpaceReclaimed: m.TotalSpaceReclaimed,
|
|
TotalFilesProcessed: m.TotalFilesProcessed,
|
|
TotalGarbageCollected: m.TotalGarbageCollected,
|
|
LastVacuumTime: m.LastVacuumTime,
|
|
AverageVacuumTime: m.AverageVacuumTime,
|
|
AverageGarbageRatio: m.AverageGarbageRatio,
|
|
SuccessfulOperations: m.SuccessfulOperations,
|
|
FailedOperations: m.FailedOperations,
|
|
CurrentGarbageRatio: m.CurrentGarbageRatio,
|
|
VolumesPendingVacuum: m.VolumesPendingVacuum,
|
|
}
|
|
}
|
|
|
|
// GetSuccessRate returns the success rate as a percentage
|
|
func (m *VacuumMetrics) GetSuccessRate() float64 {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
total := m.SuccessfulOperations + m.FailedOperations
|
|
if total == 0 {
|
|
return 100.0
|
|
}
|
|
return float64(m.SuccessfulOperations) / float64(total) * 100.0
|
|
}
|
|
|
|
// GetAverageSpaceReclaimed returns the average space reclaimed per volume
|
|
func (m *VacuumMetrics) GetAverageSpaceReclaimed() float64 {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
if m.VolumesVacuumed == 0 {
|
|
return 0
|
|
}
|
|
return float64(m.TotalSpaceReclaimed) / float64(m.VolumesVacuumed)
|
|
}
|
|
|
|
// Reset resets all metrics to zero
|
|
func (m *VacuumMetrics) Reset() {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
*m = VacuumMetrics{
|
|
LastVacuumTime: time.Now(),
|
|
}
|
|
}
|
|
|
|
// Global metrics instance for vacuum tasks
|
|
var globalVacuumMetrics = NewVacuumMetrics()
|
|
|
|
// GetGlobalVacuumMetrics returns the global vacuum metrics instance
|
|
func GetGlobalVacuumMetrics() *VacuumMetrics {
|
|
return globalVacuumMetrics
|
|
}
|