func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
	metric, err := v.metricVec.getMetricWithLabelValues(lvs...)
	if metric != nil {
		return metric.(Gauge), err
	}
	return nil, err
}
GetMetricWithLabelValues returns the Gauge for the given slice of label
values (same order as the VariableLabels in Desc). If that combination of
label values is accessed for the first time, a new Gauge is created.

It is possible to call this method without using the returned Gauge to only
create the new Gauge but leave it at its starting value 0. See also the
SummaryVec example.

Keeping the Gauge for later use is possible (and should be considered if
performance is critical), but keep in mind that Reset, DeleteLabelValues and
Delete can be used to delete the Gauge from the GaugeVec. In that case, the
Gauge will still exist, but it will not be exported anymore, even if a
Gauge with the same label values is created later. See also the CounterVec
example.

An error is returned if the number of label values is not the same as the
number of VariableLabels in Desc (minus any curried labels).

Note that for more than one label value, this method is prone to mistakes
caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
an alternative to avoid that type of mistake. For higher label numbers, the
latter has a much more readable (albeit more verbose) syntax, but it comes
with a performance overhead (for creating and processing the Labels map).
package prometheus
import (
	"math"
	"sync/atomic"
	"time"
	dto "github.com/prometheus/client_model/go"
)
type Gauge interface {
	Metric
	Collector
	Set(float64)
	Inc()
	Dec()
	Add(float64)
	Sub(float64)
	SetToCurrentTime()
}
type GaugeOpts Opts
func NewGauge(opts GaugeOpts) Gauge {
	desc := NewDesc(
		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
		opts.Help,
		nil,
		opts.ConstLabels,
	)
	result := &gauge{desc: desc, labelPairs: desc.constLabelPairs}
	result.init(result)  
	return result
}
type gauge struct {
	valBits uint64
	selfCollector
	desc       *Desc
	labelPairs []*dto.LabelPair
}
func (g *gauge) Desc() *Desc {
	return g.desc
}
func (g *gauge) Set(val float64) {
	atomic.StoreUint64(&g.valBits, math.Float64bits(val))
}
func (g *gauge) SetToCurrentTime() {
	g.Set(float64(time.Now().UnixNano()) / 1e9)
}
func (g *gauge) Inc() {
	g.Add(1)
}
func (g *gauge) Dec() {
	g.Add(-1)
}
func (g *gauge) Add(val float64) {
	for {
		oldBits := atomic.LoadUint64(&g.valBits)
		newBits := math.Float64bits(math.Float64frombits(oldBits) + val)
		if atomic.CompareAndSwapUint64(&g.valBits, oldBits, newBits) {
			return
		}
	}
}
func (g *gauge) Sub(val float64) {
	g.Add(val * -1)
}
func (g *gauge) Write(out *dto.Metric) error {
	val := math.Float64frombits(atomic.LoadUint64(&g.valBits))
	return populateMetric(GaugeValue, val, g.labelPairs, out)
}
type GaugeVec struct {
	*metricVec
}
func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
	desc := NewDesc(
		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
		opts.Help,
		labelNames,
		opts.ConstLabels,
	)
	return &GaugeVec{
		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
			if len(lvs) != len(desc.variableLabels) {
				panic(errInconsistentCardinality)
			}
			result := &gauge{desc: desc, labelPairs: makeLabelPairs(desc, lvs)}
			result.init(result)  
			return result
		}),
	}
}