Files
groot c49bfa1c34
release-tag / release-image (push) Failing after 5m54s
Vollständiges Redesign
2026-07-23 14:45:35 +02:00

68 lines
1.5 KiB
Go

package metrics
import (
"fmt"
"net/http"
"sort"
"strings"
"sync"
"sync/atomic"
)
type Registry struct {
mu sync.RWMutex
counters map[string]*atomic.Uint64
gauges map[string]*atomic.Int64
}
func New() *Registry {
return &Registry{counters: map[string]*atomic.Uint64{}, gauges: map[string]*atomic.Int64{}}
}
func (r *Registry) Counter(name string) *atomic.Uint64 {
r.mu.Lock()
defer r.mu.Unlock()
if c := r.counters[name]; c != nil {
return c
}
c := &atomic.Uint64{}
r.counters[name] = c
return c
}
func (r *Registry) Gauge(name string) *atomic.Int64 {
r.mu.Lock()
defer r.mu.Unlock()
if g := r.gauges[name]; g != nil {
return g
}
g := &atomic.Int64{}
r.gauges[name] = g
return g
}
func (r *Registry) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "text/plain; version=0.0.4")
r.mu.RLock()
defer r.mu.RUnlock()
var lines []string
for n, c := range r.counters {
lines = append(lines, fmt.Sprintf("%s %d", sanitize(n), c.Load()))
}
for n, g := range r.gauges {
lines = append(lines, fmt.Sprintf("%s %d", sanitize(n), g.Load()))
}
sort.Strings(lines)
fmt.Fprintln(w, strings.Join(lines, "\n"))
})
}
func sanitize(s string) string {
var b strings.Builder
for i, r := range s {
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9' && i > 0) || r == '_' || r == ':' {
b.WriteRune(r)
} else {
b.WriteByte('_')
}
}
return b.String()
}