2020-09-10 19:05:44 +03:00
|
|
|
// Copyright 2020 The Prometheus Authors
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package prometheus_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2023-05-03 11:46:41 +03:00
|
|
|
"google.golang.org/protobuf/proto"
|
2020-09-10 19:05:44 +03:00
|
|
|
|
|
|
|
dto "github.com/prometheus/client_model/go"
|
|
|
|
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Info implements an info pseudo-metric, which is modeled as a Gauge that
|
|
|
|
// always has a value of 1. In practice, you would just use a Gauge directly,
|
|
|
|
// but for this example, we pretend it would be useful to have a “native”
|
|
|
|
// implementation.
|
|
|
|
type Info struct {
|
|
|
|
desc *prometheus.Desc
|
|
|
|
labelPairs []*dto.LabelPair
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i Info) Desc() *prometheus.Desc {
|
|
|
|
return i.desc
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i Info) Write(out *dto.Metric) error {
|
|
|
|
out.Label = i.labelPairs
|
|
|
|
out.Gauge = &dto.Gauge{Value: proto.Float64(1)}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// InfoVec is the vector version for Info. As an info metric never changes, we
|
|
|
|
// wouldn't really need to wrap GetMetricWithLabelValues and GetMetricWith
|
|
|
|
// because Info has no additional methods compared to the vanilla Metric that
|
|
|
|
// the unwrapped MetricVec methods return. However, to demonstrate all there is
|
|
|
|
// to do to fully implement a vector for a custom Metric implementation, we do
|
|
|
|
// it in this example anyway.
|
|
|
|
type InfoVec struct {
|
|
|
|
*prometheus.MetricVec
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewInfoVec(name, help string, labelNames []string) *InfoVec {
|
|
|
|
desc := prometheus.NewDesc(name, help, labelNames, nil)
|
|
|
|
return &InfoVec{
|
|
|
|
MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric {
|
|
|
|
if len(lvs) != len(labelNames) {
|
|
|
|
panic("inconsistent label cardinality")
|
|
|
|
}
|
|
|
|
return Info{desc: desc, labelPairs: prometheus.MakeLabelPairs(desc, lvs)}
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *InfoVec) GetMetricWithLabelValues(lvs ...string) (Info, error) {
|
|
|
|
metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
|
|
|
|
return metric.(Info), err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *InfoVec) GetMetricWith(labels prometheus.Labels) (Info, error) {
|
|
|
|
metric, err := v.MetricVec.GetMetricWith(labels)
|
|
|
|
return metric.(Info), err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *InfoVec) WithLabelValues(lvs ...string) Info {
|
|
|
|
i, err := v.GetMetricWithLabelValues(lvs...)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *InfoVec) With(labels prometheus.Labels) Info {
|
|
|
|
i, err := v.GetMetricWith(labels)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *InfoVec) CurryWith(labels prometheus.Labels) (*InfoVec, error) {
|
|
|
|
vec, err := v.MetricVec.CurryWith(labels)
|
|
|
|
if vec != nil {
|
|
|
|
return &InfoVec{vec}, err
|
|
|
|
}
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *InfoVec) MustCurryWith(labels prometheus.Labels) *InfoVec {
|
|
|
|
vec, err := v.CurryWith(labels)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return vec
|
|
|
|
}
|
|
|
|
|
|
|
|
func ExampleMetricVec() {
|
|
|
|
infoVec := NewInfoVec(
|
|
|
|
"library_version_info",
|
|
|
|
"Versions of the libraries used in this binary.",
|
|
|
|
[]string{"library", "version"},
|
|
|
|
)
|
|
|
|
|
|
|
|
infoVec.WithLabelValues("prometheus/client_golang", "1.7.1")
|
|
|
|
infoVec.WithLabelValues("k8s.io/client-go", "0.18.8")
|
|
|
|
|
|
|
|
// Just for demonstration, let's check the state of the InfoVec by
|
|
|
|
// registering it with a custom registry and then let it collect the
|
|
|
|
// metrics.
|
|
|
|
reg := prometheus.NewRegistry()
|
|
|
|
reg.MustRegister(infoVec)
|
|
|
|
|
|
|
|
metricFamilies, err := reg.Gather()
|
|
|
|
if err != nil || len(metricFamilies) != 1 {
|
|
|
|
panic("unexpected behavior of custom test registry")
|
|
|
|
}
|
2023-05-03 11:46:41 +03:00
|
|
|
fmt.Println(metricFamilies[0].String())
|
2020-09-10 19:05:44 +03:00
|
|
|
|
|
|
|
// Output:
|
2023-05-03 11:46:41 +03:00
|
|
|
// name:"library_version_info" help:"Versions of the libraries used in this binary." type:GAUGE metric:<label:<name:"library" value:"k8s.io/client-go" > label:<name:"version" value:"0.18.8" > gauge:<value:1 > > metric:<label:<name:"library" value:"prometheus/client_golang" > label:<name:"version" value:"1.7.1" > gauge:<value:1 > >
|
2020-09-10 19:05:44 +03:00
|
|
|
}
|