120 lines
3.7 KiB
Go
120 lines
3.7 KiB
Go
// 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())
|
|
}
|
|
|
|
// 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()),
|
|
}
|
|
}
|