// Package metrics provides performance tracking and statistics collection. package metrics import ( "sync/atomic" "time" ) func int64Max(a, b int64) int64 { if a > b { return a } return b } // Metrics tracks various performance counters and statistics. type Metrics struct { TasksProcessed atomic.Int64 TasksFailed atomic.Int64 DataFetchTime atomic.Int64 // Total nanoseconds ExecutionTime atomic.Int64 DataTransferred atomic.Int64 // Total bytes ActiveTasks atomic.Int64 QueuedTasks atomic.Int64 PrewarmEnvHit atomic.Int64 PrewarmEnvMiss atomic.Int64 PrewarmEnvBuilt atomic.Int64 PrewarmEnvTime atomic.Int64 // Total nanoseconds PrewarmSnapshotHit atomic.Int64 PrewarmSnapshotMiss atomic.Int64 PrewarmSnapshotBuilt atomic.Int64 PrewarmSnapshotTime atomic.Int64 // Total nanoseconds } // RecordTaskSuccess records successful task completion with duration. func (m *Metrics) RecordTaskSuccess(duration time.Duration) { m.TasksProcessed.Add(1) m.ExecutionTime.Add(duration.Nanoseconds()) } // RecordTaskFailure records a task failure. func (m *Metrics) RecordTaskFailure() { m.TasksFailed.Add(1) } // RecordTaskStart records the start of a task. func (m *Metrics) RecordTaskStart() { m.ActiveTasks.Add(1) } // RecordTaskCompletion decrements the number of active tasks. It is safe to call // even if no tasks are currently recorded; the caller should ensure calls are // balanced with RecordTaskStart. func (m *Metrics) RecordTaskCompletion() { m.ActiveTasks.Add(-1) } // RecordDataTransfer records data transfer statistics. func (m *Metrics) RecordDataTransfer(bytes int64, duration time.Duration) { m.DataTransferred.Add(bytes) m.DataFetchTime.Add(duration.Nanoseconds()) } func (m *Metrics) RecordPrewarmEnvHit() { m.PrewarmEnvHit.Add(1) } func (m *Metrics) RecordPrewarmEnvMiss() { m.PrewarmEnvMiss.Add(1) } func (m *Metrics) RecordPrewarmEnvBuilt(duration time.Duration) { m.PrewarmEnvBuilt.Add(1) m.PrewarmEnvTime.Add(duration.Nanoseconds()) } func (m *Metrics) RecordPrewarmSnapshotHit() { m.PrewarmSnapshotHit.Add(1) } func (m *Metrics) RecordPrewarmSnapshotMiss() { m.PrewarmSnapshotMiss.Add(1) } func (m *Metrics) RecordPrewarmSnapshotBuilt(duration time.Duration) { m.PrewarmSnapshotBuilt.Add(1) m.PrewarmSnapshotTime.Add(duration.Nanoseconds()) } // RecordQueueLatency records the queue latency duration. // This method implements the lifecycle.MetricsRecorder interface. func (m *Metrics) RecordQueueLatency(duration time.Duration) { // Queue latency tracking is currently a no-op // This can be implemented in the future if needed } // SetQueuedTasks sets the number of queued tasks. func (m *Metrics) SetQueuedTasks(count int64) { m.QueuedTasks.Store(count) } // GetStats returns current metrics as a map. func (m *Metrics) GetStats() map[string]any { processed := m.TasksProcessed.Load() failed := m.TasksFailed.Load() dataTransferred := m.DataTransferred.Load() dataFetchTime := m.DataFetchTime.Load() return map[string]any{ "tasks_processed": processed, "tasks_failed": failed, "active_tasks": m.ActiveTasks.Load(), "queued_tasks": m.QueuedTasks.Load(), "success_rate": float64(processed-failed) / float64(int64Max(processed, 1)), "avg_exec_time": time.Duration(m.ExecutionTime.Load() / int64Max(processed, 1)), "data_transferred_gb": float64(dataTransferred) / (1024 * 1024 * 1024), "avg_fetch_time": time.Duration(dataFetchTime / int64Max(processed, 1)), "prewarm_env_hit": m.PrewarmEnvHit.Load(), "prewarm_env_miss": m.PrewarmEnvMiss.Load(), "prewarm_env_built": m.PrewarmEnvBuilt.Load(), "prewarm_env_time": time.Duration(m.PrewarmEnvTime.Load()), "prewarm_snapshot_hit": m.PrewarmSnapshotHit.Load(), "prewarm_snapshot_miss": m.PrewarmSnapshotMiss.Load(), "prewarm_snapshot_built": m.PrewarmSnapshotBuilt.Load(), "prewarm_snapshot_time": time.Duration(m.PrewarmSnapshotTime.Load()), } }