...
1
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
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
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
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
116 func (c *totalVolumesCollector) DescribeWithStability(ch chan<- *metrics.Desc) {
117 ch <- totalVolumesDesc
118 }
119
120
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