...

Source file src/k8s.io/kubernetes/pkg/kubelet/volumemanager/metrics/metrics.go

Documentation: k8s.io/kubernetes/pkg/kubelet/volumemanager/metrics

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package metrics
    18  
    19  import (
    20  	"sync"
    21  
    22  	"k8s.io/component-base/metrics"
    23  	"k8s.io/component-base/metrics/legacyregistry"
    24  	"k8s.io/kubernetes/pkg/kubelet/volumemanager/cache"
    25  	"k8s.io/kubernetes/pkg/volume"
    26  	volumeutil "k8s.io/kubernetes/pkg/volume/util"
    27  )
    28  
    29  const (
    30  	pluginNameNotAvailable = "N/A"
    31  
    32  	// Metric keys for Volume Manager.
    33  	volumeManagerTotalVolumes                     = "volume_manager_total_volumes"
    34  	reconstructVolumeOperationsTotal              = "reconstruct_volume_operations_total"
    35  	reconstructVolumeOperationsErrorsTotal        = "reconstruct_volume_operations_errors_total"
    36  	forceCleanedFailedVolumeOperationsTotal       = "force_cleaned_failed_volume_operations_total"
    37  	forceCleanedFailedVolumeOperationsErrorsTotal = "force_cleaned_failed_volume_operation_errors_total"
    38  )
    39  
    40  var (
    41  	registerMetrics sync.Once
    42  
    43  	totalVolumesDesc = metrics.NewDesc(
    44  		volumeManagerTotalVolumes,
    45  		"Number of volumes in Volume Manager",
    46  		[]string{"plugin_name", "state"},
    47  		nil,
    48  		metrics.ALPHA, "",
    49  	)
    50  
    51  	ReconstructVolumeOperationsTotal = metrics.NewCounter(
    52  		&metrics.CounterOpts{
    53  			Name:           reconstructVolumeOperationsTotal,
    54  			Help:           "The number of volumes that were attempted to be reconstructed from the operating system during kubelet startup. This includes both successful and failed reconstruction.",
    55  			StabilityLevel: metrics.ALPHA,
    56  		},
    57  	)
    58  	ReconstructVolumeOperationsErrorsTotal = metrics.NewCounter(
    59  		&metrics.CounterOpts{
    60  			Name:           reconstructVolumeOperationsErrorsTotal,
    61  			Help:           "The number of volumes that failed reconstruction from the operating system during kubelet startup.",
    62  			StabilityLevel: metrics.ALPHA,
    63  		},
    64  	)
    65  
    66  	ForceCleanedFailedVolumeOperationsTotal = metrics.NewCounter(
    67  		&metrics.CounterOpts{
    68  			Name:           forceCleanedFailedVolumeOperationsTotal,
    69  			Help:           "The number of volumes that were force cleaned after their reconstruction failed during kubelet startup. This includes both successful and failed cleanups.",
    70  			StabilityLevel: metrics.ALPHA,
    71  		},
    72  	)
    73  	ForceCleanedFailedVolumeOperationsErrorsTotal = metrics.NewCounter(
    74  		&metrics.CounterOpts{
    75  			Name:           forceCleanedFailedVolumeOperationsErrorsTotal,
    76  			Help:           "The number of volumes that failed force cleanup after their reconstruction failed during kubelet startup.",
    77  			StabilityLevel: metrics.ALPHA,
    78  		},
    79  	)
    80  )
    81  
    82  // volumeCount is a map of maps used as a counter.
    83  type volumeCount map[string]map[string]int64
    84  
    85  func (v volumeCount) add(state, plugin string) {
    86  	count, ok := v[state]
    87  	if !ok {
    88  		count = map[string]int64{}
    89  	}
    90  	count[plugin]++
    91  	v[state] = count
    92  }
    93  
    94  // Register registers Volume Manager metrics.
    95  func Register(asw cache.ActualStateOfWorld, dsw cache.DesiredStateOfWorld, pluginMgr *volume.VolumePluginMgr) {
    96  	registerMetrics.Do(func() {
    97  		legacyregistry.CustomMustRegister(&totalVolumesCollector{asw: asw, dsw: dsw, pluginMgr: pluginMgr})
    98  		legacyregistry.MustRegister(ReconstructVolumeOperationsTotal)
    99  		legacyregistry.MustRegister(ReconstructVolumeOperationsErrorsTotal)
   100  		legacyregistry.MustRegister(ForceCleanedFailedVolumeOperationsTotal)
   101  		legacyregistry.MustRegister(ForceCleanedFailedVolumeOperationsErrorsTotal)
   102  	})
   103  }
   104  
   105  type totalVolumesCollector struct {
   106  	metrics.BaseStableCollector
   107  
   108  	asw       cache.ActualStateOfWorld
   109  	dsw       cache.DesiredStateOfWorld
   110  	pluginMgr *volume.VolumePluginMgr
   111  }
   112  
   113  var _ metrics.StableCollector = &totalVolumesCollector{}
   114  
   115  // DescribeWithStability implements the metrics.StableCollector interface.
   116  func (c *totalVolumesCollector) DescribeWithStability(ch chan<- *metrics.Desc) {
   117  	ch <- totalVolumesDesc
   118  }
   119  
   120  // CollectWithStability implements the metrics.StableCollector interface.
   121  func (c *totalVolumesCollector) CollectWithStability(ch chan<- metrics.Metric) {
   122  	for stateName, pluginCount := range c.getVolumeCount() {
   123  		for pluginName, count := range pluginCount {
   124  			ch <- metrics.NewLazyConstMetric(totalVolumesDesc,
   125  				metrics.GaugeValue,
   126  				float64(count),
   127  				pluginName,
   128  				stateName)
   129  		}
   130  	}
   131  }
   132  
   133  func (c *totalVolumesCollector) getVolumeCount() volumeCount {
   134  	counter := make(volumeCount)
   135  	for _, mountedVolume := range c.asw.GetMountedVolumes() {
   136  		pluginName := volumeutil.GetFullQualifiedPluginNameForVolume(mountedVolume.PluginName, mountedVolume.VolumeSpec)
   137  		if pluginName == "" {
   138  			pluginName = pluginNameNotAvailable
   139  		}
   140  		counter.add("actual_state_of_world", pluginName)
   141  	}
   142  
   143  	for _, volumeToMount := range c.dsw.GetVolumesToMount() {
   144  		pluginName := pluginNameNotAvailable
   145  		if plugin, err := c.pluginMgr.FindPluginBySpec(volumeToMount.VolumeSpec); err == nil {
   146  			pluginName = volumeutil.GetFullQualifiedPluginNameForVolume(plugin.GetPluginName(), volumeToMount.VolumeSpec)
   147  		}
   148  		counter.add("desired_state_of_world", pluginName)
   149  	}
   150  	return counter
   151  }
   152  

View as plain text