66 lines
metrics/registry.go
Accumulates named request counters and provides a read-only snapshot.
// Package metrics provides an in-process counter registry for Prometheus export.package metricsimport ( "sync" "time")
// Counter holds a named counter value.type Counter struct { Name string Value int64}
// Snapshot is a point-in-time copy of all registered counters.type Snapshot struct {Counters []Counter
TakenAt time.Time
}
// Registry accumulates named counters for application metrics.//// All exported methods are safe for concurrent use.type Registry struct {mu sync.Mutex
counters map[string]int64}
// NewRegistry returns an initialised empty registry.func NewRegistry() *Registry { return &Registry{counters: make(map[string]int64)}}
// Inc increments the named counter by 1. Safe for concurrent use.func (r *Registry) Inc(name string) {r.mu.Lock()
defer r.mu.Unlock()r.counters[name]++
}
// Snapshot returns a read-only point-in-time copy of all counters.// Counter values are not modified by this call.func (r *Registry) Snapshot() Snapshot {r.mu.Lock()
defer r.mu.Unlock() cs := make([]Counter, 0, len(r.counters)) for name, val := range r.counters { cs = append(cs, Counter{Name: name, Value: val})}
snap := Snapshot{Counters: cs, TakenAt: time.Now()} r.counters = make(map[string]int64) return snap}
// Export returns a copy of all current counter values for the Prometheus scraper.// Safe for concurrent use.func (r *Registry) Export() map[string]int64 { result := make(map[string]int64, len(r.counters))r.mu.Lock()
defer r.mu.Unlock() for name, val := range r.counters {result[name] = val
}
return result}