package metrics import ( "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" ) type metric[T prometheus.Collector] struct { value T desc Description } // Descriptions contains metric description suitable for further processing. // The only reason for it to exist is `prometheus.Desc` disallowing field access directly. // https://github.com/prometheus/client_golang/pull/326 // https://github.com/prometheus/client_golang/issues/516 // https://github.com/prometheus/client_golang/issues/222 type Description struct { Name string `json:"name"` Help string `json:"help"` Type string `json:"type"` ConstantLabels prometheus.Labels `json:"constant_labels,omitempty"` VariableLabels []string `json:"variable_labels,omitempty"` } func newGauge(opts prometheus.GaugeOpts) metric[prometheus.Gauge] { return metric[prometheus.Gauge]{ value: prometheus.NewGauge(opts), desc: Description{ Name: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), Type: dto.MetricType_GAUGE.String(), Help: opts.Help, ConstantLabels: opts.ConstLabels, }, } } func newGaugeVec(opts prometheus.GaugeOpts, labelNames []string) metric[*prometheus.GaugeVec] { return metric[*prometheus.GaugeVec]{ value: prometheus.NewGaugeVec(opts, labelNames), desc: Description{ Name: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), Type: dto.MetricType_GAUGE.String(), Help: opts.Help, ConstantLabels: opts.ConstLabels, VariableLabels: labelNames, }, } } func newGaugeFunc(opts prometheus.GaugeOpts, f func() float64) metric[prometheus.GaugeFunc] { return metric[prometheus.GaugeFunc]{ value: prometheus.NewGaugeFunc(opts, f), desc: Description{ Name: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), Type: dto.MetricType_GAUGE.String(), Help: opts.Help, ConstantLabels: opts.ConstLabels, }, } } func newCounter(opts prometheus.CounterOpts) metric[prometheus.Counter] { return metric[prometheus.Counter]{ value: prometheus.NewCounter(opts), desc: Description{ Name: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), Type: dto.MetricType_COUNTER.String(), Help: opts.Help, ConstantLabels: opts.ConstLabels, }, } } func newCounterVec(opts prometheus.CounterOpts, labels []string) metric[*prometheus.CounterVec] { return metric[*prometheus.CounterVec]{ value: prometheus.NewCounterVec(opts, labels), desc: Description{ Name: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), Type: dto.MetricType_COUNTER.String(), Help: opts.Help, ConstantLabels: opts.ConstLabels, VariableLabels: labels, }, } } func newHistogramVec(opts prometheus.HistogramOpts, labelNames []string) metric[*prometheus.HistogramVec] { return metric[*prometheus.HistogramVec]{ value: prometheus.NewHistogramVec(opts, labelNames), desc: Description{ Name: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), Type: dto.MetricType_HISTOGRAM.String(), Help: opts.Help, ConstantLabels: opts.ConstLabels, VariableLabels: labelNames, }, } } // DescribeAll returns descriptions for all registered metrics. func DescribeAll() ([]Description, error) { registeredDescriptionsMtx.Lock() defer registeredDescriptionsMtx.Unlock() ds := make([]Description, len(registeredDescriptions)) copy(ds, registeredDescriptions) return ds, nil }