Path: blob/main/component/loki/process/internal/metric/gauges.go
4096 views
package metric12import (3"fmt"4"time"56"github.com/prometheus/client_golang/prometheus"7"github.com/prometheus/common/model"8)910const (11GaugeSet = "set"12GaugeInc = "inc"13GaugeDec = "dec"14GaugeAdd = "add"15GaugeSub = "sub"1617ErrGaugeActionRequired = "gauge action must be defined as `set`, `inc`, `dec`, `add`, or `sub`"18ErrGaugeInvalidAction = "action %s is not valid, action must be `set`, `inc`, `dec`, `add`, or `sub`"19)2021// DefaultGaugeConfig sets the defaults for a Gauge.22var DefaultGaugeConfig = GaugeConfig{23MaxIdle: 5 * time.Minute,24}2526// GaugeConfig defines a gauge metric whose value can go up or down.27type GaugeConfig struct {28// Shared fields29Name string `river:"name,attr"`30Description string `river:"description,attr,optional"`31Source string `river:"source,attr,optional"`32Prefix string `river:"prefix,attr,optional"`33MaxIdle time.Duration `river:"max_idle_duration,attr,optional"`34Value string `river:"value,attr,optional"`3536// Gauge-specific fields37Action string `river:"action,attr"`38}3940// UnmarshalRiver implements the unmarshaller41func (g *GaugeConfig) UnmarshalRiver(f func(v interface{}) error) error {42*g = DefaultGaugeConfig43type gauge GaugeConfig44err := f((*gauge)(g))45if err != nil {46return err47}4849if g.MaxIdle < 1*time.Second {50return fmt.Errorf("max_idle_duration must be greater or equal than 1s")51}5253if g.Source == "" {54g.Source = g.Name55}5657// TODO (@tpaschalis) A better way to keep track of these?58if g.Action != "set" && g.Action != "inc" && g.Action != "dec" && g.Action != "add" && g.Action != "sub" {59return fmt.Errorf("the 'action' gauge field must be one of the following values: [set, inc, dec, add, sub]")60}61return nil62}6364// Gauges is a vector of gauges for a log stream.65type Gauges struct {66*metricVec67Cfg *GaugeConfig68}6970// NewGauges creates a new gauge vec.71func NewGauges(name string, config *GaugeConfig) (*Gauges, error) {72return &Gauges{73metricVec: newMetricVec(func(labels map[string]string) prometheus.Metric {74return &expiringGauge{prometheus.NewGauge(prometheus.GaugeOpts{75Help: config.Description,76Name: name,77ConstLabels: labels,78}),790,80}81}, int64(config.MaxIdle.Seconds())),82Cfg: config,83}, nil84}8586// With returns the gauge associated with a stream labelset.87func (g *Gauges) With(labels model.LabelSet) prometheus.Gauge {88return g.metricVec.With(labels).(prometheus.Gauge)89}9091type expiringGauge struct {92prometheus.Gauge93lastModSec int6494}9596// Set sets the Gauge to an arbitrary value.97func (g *expiringGauge) Set(val float64) {98g.Gauge.Set(val)99g.lastModSec = time.Now().Unix()100}101102// Inc increments the Gauge by 1. Use Add to increment it by arbitrary103// values.104func (g *expiringGauge) Inc() {105g.Gauge.Inc()106g.lastModSec = time.Now().Unix()107}108109// Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary110// values.111func (g *expiringGauge) Dec() {112g.Gauge.Dec()113g.lastModSec = time.Now().Unix()114}115116// Add adds the given value to the Gauge. (The value can be negative,117// resulting in a decrease of the Gauge.)118func (g *expiringGauge) Add(val float64) {119g.Gauge.Add(val)120g.lastModSec = time.Now().Unix()121}122123// Sub subtracts the given value from the Gauge. (The value can be124// negative, resulting in an increase of the Gauge.)125func (g *expiringGauge) Sub(val float64) {126g.Gauge.Sub(val)127g.lastModSec = time.Now().Unix()128}129130// SetToCurrentTime sets the Gauge to the current Unix time in seconds.131func (g *expiringGauge) SetToCurrentTime() {132g.Gauge.SetToCurrentTime()133g.lastModSec = time.Now().Unix()134}135136// HasExpired implements Expirable137func (g *expiringGauge) HasExpired(currentTimeSec int64, maxAgeSec int64) bool {138return currentTimeSec-g.lastModSec >= maxAgeSec139}140141142