Extend prometheus.Desc
This commit is contained in:
		
							
								
								
									
										179
									
								
								staging/src/k8s.io/component-base/metrics/desc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								staging/src/k8s.io/component-base/metrics/desc.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var hiddenFlag = "metricsshouldbehidden"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO(RainbowMango): replace by stabilityLevel.setDefault() after PR(https://github.com/kubernetes/kubernetes/pull/82957) be merged.
 | 
				
			||||||
 | 
						if stabilityLevel == "" {
 | 
				
			||||||
 | 
							d.stabilityLevel = ALPHA
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							d.stabilityLevel = stabilityLevel
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d.deprecatedVersion = deprecatedVersion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// markHidden mark a special flag to 'HELP'.
 | 
				
			||||||
 | 
					// The metrics marked with this flag will be ignored when collecting automatically.
 | 
				
			||||||
 | 
					func (d *Desc) markHidden() {
 | 
				
			||||||
 | 
						d.hideOnce.Do(func() {
 | 
				
			||||||
 | 
							d.help = fmt.Sprintf("(%s) %s", hiddenFlag, 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()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *Desc) initializeHiddenDesc() {
 | 
				
			||||||
 | 
						d.markHidden()
 | 
				
			||||||
 | 
						d.initializeDeprecatedDesc()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user