// steamcache/metrics/metrics.go package metrics import ( "sync" "sync/atomic" "time" ) // Metrics tracks various performance and operational metrics type Metrics struct { // Request metrics TotalRequests int64 CacheHits int64 CacheMisses int64 CacheCoalesced int64 Errors int64 RateLimited int64 // Performance metrics TotalResponseTime int64 // in nanoseconds TotalBytesServed int64 TotalBytesCached int64 // Cache metrics MemoryCacheSize int64 DiskCacheSize int64 MemoryCacheHits int64 DiskCacheHits int64 // Service metrics ServiceRequests map[string]int64 serviceMutex sync.RWMutex // Time tracking StartTime time.Time LastResetTime time.Time } // NewMetrics creates a new metrics instance func NewMetrics() *Metrics { now := time.Now() return &Metrics{ ServiceRequests: make(map[string]int64), StartTime: now, LastResetTime: now, } } // IncrementTotalRequests increments the total request counter func (m *Metrics) IncrementTotalRequests() { atomic.AddInt64(&m.TotalRequests, 1) } // IncrementCacheHits increments the cache hit counter func (m *Metrics) IncrementCacheHits() { atomic.AddInt64(&m.CacheHits, 1) } // IncrementCacheMisses increments the cache miss counter func (m *Metrics) IncrementCacheMisses() { atomic.AddInt64(&m.CacheMisses, 1) } // IncrementCacheCoalesced increments the coalesced request counter func (m *Metrics) IncrementCacheCoalesced() { atomic.AddInt64(&m.CacheCoalesced, 1) } // IncrementErrors increments the error counter func (m *Metrics) IncrementErrors() { atomic.AddInt64(&m.Errors, 1) } // IncrementRateLimited increments the rate limited counter func (m *Metrics) IncrementRateLimited() { atomic.AddInt64(&m.RateLimited, 1) } // AddResponseTime adds response time to the total func (m *Metrics) AddResponseTime(duration time.Duration) { atomic.AddInt64(&m.TotalResponseTime, int64(duration)) } // AddBytesServed adds bytes served to the total func (m *Metrics) AddBytesServed(bytes int64) { atomic.AddInt64(&m.TotalBytesServed, bytes) } // AddBytesCached adds bytes cached to the total func (m *Metrics) AddBytesCached(bytes int64) { atomic.AddInt64(&m.TotalBytesCached, bytes) } // SetMemoryCacheSize sets the current memory cache size func (m *Metrics) SetMemoryCacheSize(size int64) { atomic.StoreInt64(&m.MemoryCacheSize, size) } // SetDiskCacheSize sets the current disk cache size func (m *Metrics) SetDiskCacheSize(size int64) { atomic.StoreInt64(&m.DiskCacheSize, size) } // IncrementMemoryCacheHits increments memory cache hits func (m *Metrics) IncrementMemoryCacheHits() { atomic.AddInt64(&m.MemoryCacheHits, 1) } // IncrementDiskCacheHits increments disk cache hits func (m *Metrics) IncrementDiskCacheHits() { atomic.AddInt64(&m.DiskCacheHits, 1) } // IncrementServiceRequests increments requests for a specific service func (m *Metrics) IncrementServiceRequests(service string) { m.serviceMutex.Lock() defer m.serviceMutex.Unlock() m.ServiceRequests[service]++ } // GetServiceRequests returns the number of requests for a service func (m *Metrics) GetServiceRequests(service string) int64 { m.serviceMutex.RLock() defer m.serviceMutex.RUnlock() return m.ServiceRequests[service] } // GetStats returns a snapshot of current metrics func (m *Metrics) GetStats() *Stats { totalRequests := atomic.LoadInt64(&m.TotalRequests) cacheHits := atomic.LoadInt64(&m.CacheHits) cacheMisses := atomic.LoadInt64(&m.CacheMisses) var hitRate float64 if totalRequests > 0 { hitRate = float64(cacheHits) / float64(totalRequests) } var avgResponseTime time.Duration if totalRequests > 0 { avgResponseTime = time.Duration(atomic.LoadInt64(&m.TotalResponseTime) / totalRequests) } m.serviceMutex.RLock() serviceRequests := make(map[string]int64) for k, v := range m.ServiceRequests { serviceRequests[k] = v } m.serviceMutex.RUnlock() return &Stats{ TotalRequests: totalRequests, CacheHits: cacheHits, CacheMisses: cacheMisses, CacheCoalesced: atomic.LoadInt64(&m.CacheCoalesced), Errors: atomic.LoadInt64(&m.Errors), RateLimited: atomic.LoadInt64(&m.RateLimited), HitRate: hitRate, AvgResponseTime: avgResponseTime, TotalBytesServed: atomic.LoadInt64(&m.TotalBytesServed), TotalBytesCached: atomic.LoadInt64(&m.TotalBytesCached), MemoryCacheSize: atomic.LoadInt64(&m.MemoryCacheSize), DiskCacheSize: atomic.LoadInt64(&m.DiskCacheSize), MemoryCacheHits: atomic.LoadInt64(&m.MemoryCacheHits), DiskCacheHits: atomic.LoadInt64(&m.DiskCacheHits), ServiceRequests: serviceRequests, Uptime: time.Since(m.StartTime), LastResetTime: m.LastResetTime, } } // Reset resets all metrics to zero func (m *Metrics) Reset() { atomic.StoreInt64(&m.TotalRequests, 0) atomic.StoreInt64(&m.CacheHits, 0) atomic.StoreInt64(&m.CacheMisses, 0) atomic.StoreInt64(&m.CacheCoalesced, 0) atomic.StoreInt64(&m.Errors, 0) atomic.StoreInt64(&m.RateLimited, 0) atomic.StoreInt64(&m.TotalResponseTime, 0) atomic.StoreInt64(&m.TotalBytesServed, 0) atomic.StoreInt64(&m.TotalBytesCached, 0) atomic.StoreInt64(&m.MemoryCacheHits, 0) atomic.StoreInt64(&m.DiskCacheHits, 0) m.serviceMutex.Lock() m.ServiceRequests = make(map[string]int64) m.serviceMutex.Unlock() m.LastResetTime = time.Now() } // Stats represents a snapshot of metrics type Stats struct { TotalRequests int64 CacheHits int64 CacheMisses int64 CacheCoalesced int64 Errors int64 RateLimited int64 HitRate float64 AvgResponseTime time.Duration TotalBytesServed int64 TotalBytesCached int64 MemoryCacheSize int64 DiskCacheSize int64 MemoryCacheHits int64 DiskCacheHits int64 ServiceRequests map[string]int64 Uptime time.Duration LastResetTime time.Time }