Skip to content

Commit

Permalink
observability: add prometheus variable labels; remove collector
Browse files Browse the repository at this point in the history
* polymorphic `statsValue`
  - remove `switch kind`
* part five, prev. commit: 9290dc5

Signed-off-by: Alex Aizman <[email protected]>
  • Loading branch information
alex-aizman committed Dec 26, 2024
1 parent b429fca commit 3b323ff
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 54 deletions.
21 changes: 13 additions & 8 deletions stats/common_prom.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

type (
statsValue struct {
prom iadd
iadd iadd
kind string // enum { KindCounter, ..., KindSpecial }
Value int64 `json:"v,string"`
numSamples int64 // (average latency over stats_time)
Expand Down Expand Up @@ -218,25 +218,30 @@ func (r *runner) reg(snode *meta.Snode, name, kind string, extra *Extra) {
opts := prometheus.CounterOpts{Namespace: "ais", Subsystem: snode.Type(), Name: metricName, Help: help, ConstLabels: constLabs}
if len(extra.VarLabs) > 0 {
metric := prometheus.NewCounterVec(opts, extra.VarLabs)
v.prom = counterVec{metric}
v.iadd = counterVec{metric}
promRegistry.MustRegister(metric)
} else {
metric := prometheus.NewCounter(opts)
v.prom = counter{metric}
v.iadd = counter{metric}
promRegistry.MustRegister(metric)
}
case KindLatency, KindThroughput:
// these two _kinds_ or, more generally, metrics computed over fixed ('periodic.stats_time') interval
// are now completely hidden from prometheus (v3.26)

case KindLatency:
// computed over 'periodic.stats_time'; used for logs; hidden from prometheus (v3.26)
v.iadd = latency{}
case KindThroughput:
// ditto (v3.26)
v.iadd = throughput{}

default:
opts := prometheus.GaugeOpts{Namespace: "ais", Subsystem: snode.Type(), Name: metricName, Help: help, ConstLabels: constLabs}
if len(extra.VarLabs) > 0 {
metric := prometheus.NewGaugeVec(opts, extra.VarLabs)
v.prom = gaugeVec{metric}
v.iadd = gaugeVec{metric}
promRegistry.MustRegister(metric)
} else {
metric := prometheus.NewGauge(opts)
v.prom = gauge{metric}
v.iadd = gauge{metric}
promRegistry.MustRegister(metric)
}
}
Expand Down
103 changes: 57 additions & 46 deletions stats/prom.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,83 +18,94 @@ import (

type (
iadd interface {
add(val int64)
addWith(val int64, vlabs map[string]string)
add(parent *statsValue, val int64)
addWith(parent *statsValue, nv cos.NamedVal64)
}

latency struct{}
throughput struct{}

counter struct{ prometheus.Counter }
counterVec struct{ *prometheus.CounterVec }
gauge struct{ prometheus.Gauge }
gaugeVec struct{ *prometheus.GaugeVec }
)

func (v counter) add(val int64) { v.Add(float64(val)) }
func (counter) addWith(int64, map[string]string) { debug.Assert(false) }
//
// internal (computed) latency & throughput -----
//

func (counterVec) add(int64) { debug.Assert(false) }
func (v counterVec) addWith(val int64, vlabs map[string]string) { v.With(vlabs).Add(float64(val)) }
func (latency) add(parent *statsValue, val int64) {
ratomic.AddInt64(&parent.numSamples, 1)
ratomic.AddInt64(&parent.Value, val)
ratomic.AddInt64(&parent.cumulative, val)
}

func (v gauge) add(val int64) { v.Add(float64(val)) }
func (gauge) addWith(int64, map[string]string) { debug.Assert(false) }
func (v latency) addWith(parent *statsValue, nv cos.NamedVal64) {
v.add(parent, nv.Value)
}

func (gaugeVec) add(int64) { debug.Assert(false) }
func (v gaugeVec) addWith(val int64, vlabs map[string]string) { v.With(vlabs).Add(float64(val)) }
func (throughput) add(parent *statsValue, val int64) {
ratomic.AddInt64(&parent.Value, val)
ratomic.AddInt64(&parent.cumulative, val)
}

func (v throughput) addWith(parent *statsValue, nv cos.NamedVal64) {
v.add(parent, nv.Value)
}

//
// as adder
// prometheus ---------------------------------
//

func (v counter) add(parent *statsValue, val int64) {
ratomic.AddInt64(&parent.Value, val)
v.Add(float64(val))
}

func (v counterVec) addWith(parent *statsValue, nv cos.NamedVal64) {
ratomic.AddInt64(&parent.Value, nv.Value)
v.With(nv.VarLabs).Add(float64(nv.Value))
}

func (v gauge) add(parent *statsValue, val int64) {
ratomic.AddInt64(&parent.Value, val)
v.Add(float64(val))
}

func (v gaugeVec) addWith(parent *statsValue, nv cos.NamedVal64) {
ratomic.AddInt64(&parent.Value, nv.Value)
v.With(nv.VarLabs).Add(float64(nv.Value))
}

// illegal

func (counter) addWith(*statsValue, cos.NamedVal64) { debug.Assert(false) }
func (counterVec) add(*statsValue, int64) { debug.Assert(false) }
func (gauge) addWith(*statsValue, cos.NamedVal64) { debug.Assert(false) }
func (gaugeVec) add(*statsValue, int64) { debug.Assert(false) }

// coreStats

func (s *coreStats) add(name string, val int64) {
v, ok := s.Tracker[name]
debug.Assertf(ok, "invalid metric name %q", name)

switch v.kind {
// internal/computed + log
case KindLatency:
ratomic.AddInt64(&v.numSamples, 1)
fallthrough
case KindThroughput:
ratomic.AddInt64(&v.Value, val)
ratomic.AddInt64(&v.cumulative, val)

// incl. prometheus; no variable labels
case KindCounter, KindSize, KindTotal:
ratomic.AddInt64(&v.Value, val)
v.prom.add(val)

default:
debug.Assert(false, v.kind)
}
v.iadd.add(v, val)
}

func (s *coreStats) addWith(nv cos.NamedVal64) {
v, ok := s.Tracker[nv.Name]
debug.Assertf(ok, "invalid metric name %q", nv.Name)

switch v.kind {
// internal/computed + log
case KindLatency:
ratomic.AddInt64(&v.numSamples, 1)
fallthrough
case KindThroughput:
ratomic.AddInt64(&v.Value, nv.Value)
ratomic.AddInt64(&v.cumulative, nv.Value)

// incl. prometheus; with variable labels
case KindCounter, KindSize, KindTotal:
ratomic.AddInt64(&v.Value, nv.Value)
v.prom.addWith(nv.Value, nv.VarLabs)

default:
debug.Assert(false, v.kind)
}
v.iadd.addWith(v, nv)
}

func (s *coreStats) updateUptime(d time.Duration) {
v := s.Tracker[Uptime]
ratomic.StoreInt64(&v.Value, d.Nanoseconds())

vprom, ok := v.prom.(gauge)
vprom, ok := v.iadd.(gauge)
debug.Assert(ok, Uptime)

vprom.Set(d.Seconds())
Expand Down

0 comments on commit 3b323ff

Please sign in to comment.