mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #83062 from RainbowMango/pr_provide_custom_collector_support
Provide a mechanism for custom collectors to use the metrics stability framework
This commit is contained in:
commit
76d04cf602
@ -3,7 +3,9 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"collector.go",
|
||||
"counter.go",
|
||||
"desc.go",
|
||||
"gauge.go",
|
||||
"histogram.go",
|
||||
"http.go",
|
||||
@ -13,6 +15,7 @@ go_library(
|
||||
"processstarttime.go",
|
||||
"registry.go",
|
||||
"summary.go",
|
||||
"value.go",
|
||||
"version.go",
|
||||
"version_parser.go",
|
||||
"wrappers.go",
|
||||
@ -35,6 +38,7 @@ go_library(
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"collector_test.go",
|
||||
"counter_test.go",
|
||||
"gauge_test.go",
|
||||
"histogram_test.go",
|
||||
@ -49,6 +53,7 @@ go_test(
|
||||
"//vendor/github.com/blang/semver:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus/testutil:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_model/go:go_default_library",
|
||||
"//vendor/github.com/prometheus/common/expfmt:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
],
|
||||
|
148
staging/src/k8s.io/component-base/metrics/collector.go
Normal file
148
staging/src/k8s.io/component-base/metrics/collector.go
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes 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 metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// StableCollector extends the prometheus.Collector interface to allow customization of the
|
||||
// metric registration process, it's especially intend to be used in scenario of custom collector.
|
||||
type StableCollector interface {
|
||||
prometheus.Collector
|
||||
|
||||
// DescribeWithStability sends the super-set of all possible metrics.Desc collected
|
||||
// by this StableCollector to the provided channel.
|
||||
DescribeWithStability(chan<- *Desc)
|
||||
|
||||
// CollectWithStability sends each collected metrics.Metric via the provide channel.
|
||||
CollectWithStability(chan<- Metric)
|
||||
|
||||
// Create will initialize all Desc and it intends to be called by registry.
|
||||
Create(version *semver.Version, self StableCollector) bool
|
||||
}
|
||||
|
||||
// BaseStableCollector which implements almost all of the methods defined by StableCollector
|
||||
// is a convenient assistant for custom collectors.
|
||||
// It is recommend that inherit BaseStableCollector when implementing custom collectors.
|
||||
type BaseStableCollector struct {
|
||||
descriptors []*Desc // stores all Desc collected from DescribeWithStability().
|
||||
registrable []*Desc // stores registrable Desc(not be hidden), is a subset of descriptors.
|
||||
self StableCollector
|
||||
}
|
||||
|
||||
// DescribeWithStability sends all descriptors to the provided channel.
|
||||
// Every custom collector should over-write this method.
|
||||
func (bsc *BaseStableCollector) DescribeWithStability(ch chan<- *Desc) {
|
||||
panic(fmt.Errorf("custom collector should over-write DescribeWithStability method"))
|
||||
}
|
||||
|
||||
// Describe sends all descriptors to the provided channel.
|
||||
// It intend to be called by prometheus registry.
|
||||
func (bsc *BaseStableCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
for _, d := range bsc.registrable {
|
||||
ch <- d.toPrometheusDesc()
|
||||
}
|
||||
}
|
||||
|
||||
// CollectWithStability sends all metrics to the provided channel.
|
||||
// Every custom collector should over-write this method.
|
||||
func (bsc *BaseStableCollector) CollectWithStability(ch chan<- Metric) {
|
||||
panic(fmt.Errorf("custom collector should over-write CollectWithStability method"))
|
||||
}
|
||||
|
||||
// Collect is called by the Prometheus registry when collecting metrics.
|
||||
func (bsc *BaseStableCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
mch := make(chan Metric)
|
||||
|
||||
go func() {
|
||||
bsc.self.CollectWithStability(mch)
|
||||
close(mch)
|
||||
}()
|
||||
|
||||
for m := range mch {
|
||||
// nil Metric usually means hidden metrics
|
||||
if m == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.Metric(m)
|
||||
}
|
||||
}
|
||||
|
||||
func (bsc *BaseStableCollector) add(d *Desc) {
|
||||
bsc.descriptors = append(bsc.descriptors, d)
|
||||
}
|
||||
|
||||
// Init intends to be called by registry.
|
||||
func (bsc *BaseStableCollector) init(self StableCollector) {
|
||||
bsc.self = self
|
||||
|
||||
dch := make(chan *Desc)
|
||||
|
||||
// collect all possible descriptions from custom side
|
||||
go func() {
|
||||
bsc.self.DescribeWithStability(dch)
|
||||
close(dch)
|
||||
}()
|
||||
|
||||
for d := range dch {
|
||||
bsc.add(d)
|
||||
}
|
||||
}
|
||||
|
||||
// Create intends to be called by registry.
|
||||
// Create will return true as long as there is one or more metrics not be hidden.
|
||||
// Otherwise return false, that means the whole collector will be ignored by registry.
|
||||
func (bsc *BaseStableCollector) Create(version *semver.Version, self StableCollector) bool {
|
||||
bsc.init(self)
|
||||
|
||||
for _, d := range bsc.descriptors {
|
||||
if version != nil {
|
||||
d.determineDeprecationStatus(*version)
|
||||
}
|
||||
|
||||
d.createOnce.Do(func() {
|
||||
d.createLock.Lock()
|
||||
defer d.createLock.Unlock()
|
||||
|
||||
if d.IsHidden() {
|
||||
// do nothing for hidden metrics
|
||||
} else if d.IsDeprecated() {
|
||||
d.initializeDeprecatedDesc()
|
||||
bsc.registrable = append(bsc.registrable, d)
|
||||
d.isCreated = true
|
||||
} else {
|
||||
d.initialize()
|
||||
bsc.registrable = append(bsc.registrable, d)
|
||||
d.isCreated = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if len(bsc.registrable) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if our BaseStableCollector implements necessary interface
|
||||
var _ StableCollector = &BaseStableCollector{}
|
153
staging/src/k8s.io/component-base/metrics/collector_test.go
Normal file
153
staging/src/k8s.io/component-base/metrics/collector_test.go
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes 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 metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
)
|
||||
|
||||
type testCustomCollector struct {
|
||||
BaseStableCollector
|
||||
}
|
||||
|
||||
var (
|
||||
currentVersion = apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "17",
|
||||
GitVersion: "v1.17.0-alpha-1.12345",
|
||||
}
|
||||
alphaDesc = NewDesc("metric_alpha", "alpha metric", []string{"name"}, nil,
|
||||
ALPHA, "")
|
||||
stableDesc = NewDesc("metric_stable", "stable metrics", []string{"name"}, nil,
|
||||
STABLE, "")
|
||||
deprecatedDesc = NewDesc("metric_deprecated", "stable deprecated metrics", []string{"name"}, nil,
|
||||
STABLE, "1.17.0")
|
||||
hiddenDesc = NewDesc("metric_hidden", "stable hidden metrics", []string{"name"}, nil,
|
||||
STABLE, "1.16.0")
|
||||
)
|
||||
|
||||
func (tc *testCustomCollector) DescribeWithStability(ch chan<- *Desc) {
|
||||
ch <- alphaDesc
|
||||
ch <- stableDesc
|
||||
ch <- deprecatedDesc
|
||||
ch <- hiddenDesc
|
||||
}
|
||||
|
||||
func (tc *testCustomCollector) CollectWithStability(ch chan<- Metric) {
|
||||
ch <- NewLazyConstMetric(
|
||||
alphaDesc,
|
||||
GaugeValue,
|
||||
1,
|
||||
"value",
|
||||
)
|
||||
ch <- NewLazyConstMetric(
|
||||
stableDesc,
|
||||
GaugeValue,
|
||||
1,
|
||||
"value",
|
||||
)
|
||||
ch <- NewLazyConstMetric(
|
||||
deprecatedDesc,
|
||||
GaugeValue,
|
||||
1,
|
||||
"value",
|
||||
)
|
||||
ch <- NewLazyConstMetric(
|
||||
hiddenDesc,
|
||||
GaugeValue,
|
||||
1,
|
||||
"value",
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
func getMetric(metrics []*dto.MetricFamily, fqName string) *dto.MetricFamily {
|
||||
for _, m := range metrics {
|
||||
if *m.Name == fqName {
|
||||
return m
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestBaseCustomCollector(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
d *Desc
|
||||
shouldHidden bool
|
||||
expectedHelp string
|
||||
}{
|
||||
{
|
||||
name: "alpha metric should contains stability metadata",
|
||||
d: alphaDesc,
|
||||
shouldHidden: false,
|
||||
expectedHelp: "[ALPHA] alpha metric",
|
||||
},
|
||||
{
|
||||
name: "stable metric should contains stability metadata",
|
||||
d: stableDesc,
|
||||
shouldHidden: false,
|
||||
expectedHelp: "[STABLE] stable metrics",
|
||||
},
|
||||
{
|
||||
name: "deprecated metric should contains stability metadata",
|
||||
d: deprecatedDesc,
|
||||
shouldHidden: false,
|
||||
expectedHelp: "[STABLE] (Deprecated since 1.17.0) stable deprecated metrics",
|
||||
},
|
||||
{
|
||||
name: "hidden metric should be ignored",
|
||||
d: hiddenDesc,
|
||||
shouldHidden: true,
|
||||
expectedHelp: "[STABLE] stable hidden metrics",
|
||||
},
|
||||
}
|
||||
|
||||
registry := newKubeRegistry(currentVersion)
|
||||
customCollector := &testCustomCollector{}
|
||||
|
||||
if err := registry.CustomRegister(customCollector); err != nil {
|
||||
t.Fatalf("register collector failed with err: %v", err)
|
||||
}
|
||||
|
||||
metrics, err := registry.Gather()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get metrics from collector, %v", err)
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
tc := test
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
m := getMetric(metrics, tc.d.fqName)
|
||||
if m == nil {
|
||||
if !tc.shouldHidden {
|
||||
t.Fatalf("Want metric: %s", tc.d.fqName)
|
||||
}
|
||||
} else {
|
||||
if m.GetHelp() != tc.expectedHelp {
|
||||
t.Fatalf("Metric(%s) HELP(%s) not contains: %s", tc.d.fqName, *m.Help, tc.expectedHelp)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
158
staging/src/k8s.io/component-base/metrics/desc.go
Normal file
158
staging/src/k8s.io/component-base/metrics/desc.go
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes 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 metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// Desc is a prometheus.Desc extension.
|
||||
//
|
||||
// Use NewDesc to create new Desc instances.
|
||||
type Desc struct {
|
||||
// fqName has been built from Namespace, Subsystem, and Name.
|
||||
fqName string
|
||||
// help provides some helpful information about this metric.
|
||||
help string
|
||||
// constLabels is the label names. Their label values are variable.
|
||||
constLabels Labels
|
||||
// variableLabels contains names of labels for which the metric
|
||||
// maintains variable values.
|
||||
variableLabels []string
|
||||
|
||||
// promDesc is the descriptor used by every Prometheus Metric.
|
||||
promDesc *prometheus.Desc
|
||||
|
||||
// stabilityLevel represents the API guarantees for a given defined metric.
|
||||
stabilityLevel StabilityLevel
|
||||
// deprecatedVersion represents in which version this metric be deprecated.
|
||||
deprecatedVersion string
|
||||
|
||||
isDeprecated bool
|
||||
isHidden bool
|
||||
isCreated bool
|
||||
createLock sync.RWMutex
|
||||
markDeprecationOnce sync.Once
|
||||
createOnce sync.Once
|
||||
deprecateOnce sync.Once
|
||||
hideOnce sync.Once
|
||||
annotateOnce sync.Once
|
||||
}
|
||||
|
||||
// NewDesc extends prometheus.NewDesc with stability support.
|
||||
//
|
||||
// The stabilityLevel should be valid stability label, such as "metrics.ALPHA"
|
||||
// and "metrics.STABLE"(Maybe "metrics.BETA" in future). Default value "metrics.ALPHA"
|
||||
// will be used in case of empty or invalid stability label.
|
||||
//
|
||||
// The deprecatedVersion represents in which version this Metric be deprecated.
|
||||
// The deprecation policy outlined by the control plane metrics stability KEP.
|
||||
func NewDesc(fqName string, help string, variableLabels []string, constLabels Labels,
|
||||
stabilityLevel StabilityLevel, deprecatedVersion string) *Desc {
|
||||
d := &Desc{
|
||||
fqName: fqName,
|
||||
help: help,
|
||||
variableLabels: variableLabels,
|
||||
constLabels: constLabels,
|
||||
stabilityLevel: stabilityLevel,
|
||||
deprecatedVersion: deprecatedVersion,
|
||||
}
|
||||
d.stabilityLevel.setDefaults()
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
// String formats the Desc as a string.
|
||||
// The stability metadata maybe annotated in 'HELP' section if called after registry,
|
||||
// otherwise not.
|
||||
func (d *Desc) String() string {
|
||||
if d.isCreated {
|
||||
return d.promDesc.String()
|
||||
}
|
||||
|
||||
return prometheus.NewDesc(d.fqName, d.help, d.variableLabels, prometheus.Labels(d.constLabels)).String()
|
||||
}
|
||||
|
||||
// toPrometheusDesc transform self to prometheus.Desc
|
||||
func (d *Desc) toPrometheusDesc() *prometheus.Desc {
|
||||
return d.promDesc
|
||||
}
|
||||
|
||||
// DeprecatedVersion returns a pointer to the Version or nil
|
||||
func (d *Desc) DeprecatedVersion() *semver.Version {
|
||||
return parseSemver(d.deprecatedVersion)
|
||||
|
||||
}
|
||||
|
||||
func (d *Desc) determineDeprecationStatus(version semver.Version) {
|
||||
selfVersion := d.DeprecatedVersion()
|
||||
if selfVersion == nil {
|
||||
return
|
||||
}
|
||||
d.markDeprecationOnce.Do(func() {
|
||||
if selfVersion.LTE(version) {
|
||||
d.isDeprecated = true
|
||||
}
|
||||
if ShouldShowHidden() {
|
||||
klog.Warningf("Hidden metrics(%s) have been manually overridden, showing this very deprecated metric.", d.fqName)
|
||||
return
|
||||
}
|
||||
if shouldHide(&version, selfVersion) {
|
||||
klog.Warningf("This metric(%s) has been deprecated for more than one release, hiding.", d.fqName)
|
||||
d.isHidden = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// IsHidden returns if metric will be hidden
|
||||
func (d *Desc) IsHidden() bool {
|
||||
return d.isHidden
|
||||
}
|
||||
|
||||
// IsDeprecated returns if metric has been deprecated
|
||||
func (d *Desc) IsDeprecated() bool {
|
||||
return d.isDeprecated
|
||||
}
|
||||
|
||||
func (d *Desc) markDeprecated() {
|
||||
d.deprecateOnce.Do(func() {
|
||||
d.help = fmt.Sprintf("(Deprecated since %s) %s", d.deprecatedVersion, d.help)
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Desc) annotateStabilityLevel() {
|
||||
d.annotateOnce.Do(func() {
|
||||
d.help = fmt.Sprintf("[%v] %v", d.stabilityLevel, d.help)
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Desc) initialize() {
|
||||
d.annotateStabilityLevel()
|
||||
// this actually creates the underlying prometheus desc.
|
||||
d.promDesc = prometheus.NewDesc(d.fqName, d.help, d.variableLabels, prometheus.Labels(d.constLabels))
|
||||
}
|
||||
|
||||
func (d *Desc) initializeDeprecatedDesc() {
|
||||
d.markDeprecated()
|
||||
d.initialize()
|
||||
}
|
@ -85,3 +85,22 @@ func RawRegister(c prometheus.Collector) error {
|
||||
prometheus.Register(c)
|
||||
return err
|
||||
}
|
||||
|
||||
// CustomRegister registers a custom collector but uses the global registry.
|
||||
func CustomRegister(c metrics.StableCollector) error {
|
||||
err := defaultRegistry.CustomRegister(c)
|
||||
|
||||
//TODO(RainbowMango): Maybe we can wrap this error by error wrapping.(Golang 1.13)
|
||||
_ = prometheus.Register(c)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// CustomMustRegister registers custom collectors but uses the global registry.
|
||||
func CustomMustRegister(cs ...metrics.StableCollector) {
|
||||
defaultRegistry.CustomMustRegister(cs...)
|
||||
|
||||
for _, c := range cs {
|
||||
prometheus.MustRegister(c)
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,8 @@ type KubeRegistry interface {
|
||||
RawRegister(prometheus.Collector) error
|
||||
// Deprecated
|
||||
RawMustRegister(...prometheus.Collector)
|
||||
CustomRegister(c StableCollector) error
|
||||
CustomMustRegister(cs ...StableCollector)
|
||||
Register(Registerable) error
|
||||
MustRegister(...Registerable)
|
||||
Unregister(Registerable) bool
|
||||
@ -117,6 +119,29 @@ func (kr *kubeRegistry) MustRegister(cs ...Registerable) {
|
||||
kr.PromRegistry.MustRegister(metrics...)
|
||||
}
|
||||
|
||||
// CustomRegister registers a new custom collector.
|
||||
func (kr *kubeRegistry) CustomRegister(c StableCollector) error {
|
||||
if c.Create(&kr.version, c) {
|
||||
return kr.PromRegistry.Register(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CustomMustRegister works like CustomRegister but registers any number of
|
||||
// StableCollectors and panics upon the first registration that causes an
|
||||
// error.
|
||||
func (kr *kubeRegistry) CustomMustRegister(cs ...StableCollector) {
|
||||
collectors := make([]prometheus.Collector, 0, len(cs))
|
||||
for _, c := range cs {
|
||||
if c.Create(&kr.version, c) {
|
||||
collectors = append(collectors, c)
|
||||
}
|
||||
}
|
||||
|
||||
kr.PromRegistry.MustRegister(collectors...)
|
||||
}
|
||||
|
||||
// RawRegister takes a native prometheus.Collector and registers the collector
|
||||
// to the registry. This bypasses metrics safety checks, so should only be used
|
||||
// to register custom prometheus collectors.
|
||||
|
46
staging/src/k8s.io/component-base/metrics/value.go
Normal file
46
staging/src/k8s.io/component-base/metrics/value.go
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes 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 metrics
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// ValueType is an enumeration of metric types that represent a simple value.
|
||||
type ValueType int
|
||||
|
||||
// Possible values for the ValueType enum.
|
||||
const (
|
||||
_ ValueType = iota
|
||||
CounterValue
|
||||
GaugeValue
|
||||
UntypedValue
|
||||
)
|
||||
|
||||
func (vt *ValueType) toPromValueType() prometheus.ValueType {
|
||||
return prometheus.ValueType(*vt)
|
||||
}
|
||||
|
||||
// NewLazyConstMetric is a helper of MustNewConstMetric.
|
||||
//
|
||||
// Note: If the metrics described by the desc is hidden, the metrics will not be created.
|
||||
func NewLazyConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric {
|
||||
if desc.IsHidden() {
|
||||
return nil
|
||||
}
|
||||
return prometheus.MustNewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...)
|
||||
}
|
Loading…
Reference in New Issue
Block a user