github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/ndm-exporter/collector/static.go (about) 1 /* 2 Copyright 2019 The OpenEBS 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 collector 18 19 import ( 20 "sync" 21 22 "github.com/openebs/node-disk-manager/db/kubernetes" 23 "github.com/openebs/node-disk-manager/pkg/metrics/static" 24 25 "github.com/prometheus/client_golang/prometheus" 26 "k8s.io/klog/v2" 27 ) 28 29 // StaticMetricCollector contains the metrics, concurrency handler and client to get the 30 // static metrics 31 type StaticMetricCollector struct { 32 // Client is the k8s client which will be used to interface with etcd 33 Client kubernetes.Client 34 35 // concurrency handling 36 sync.Mutex 37 requestInProgress bool 38 39 // all the exposed metrics 40 metrics *static.Metrics 41 } 42 43 // NewStaticMetricCollector creates a new instance of StaticMetricCollector which 44 // implements Collector interface 45 func NewStaticMetricCollector(c kubernetes.Client) prometheus.Collector { 46 klog.V(2).Infof("Static Metric Collector initialized") 47 return &StaticMetricCollector{ 48 Client: c, 49 metrics: static.NewMetrics(), 50 } 51 } 52 53 // setRequestProgressToFalse is used to set the progress flag, when a request is 54 // processed or errored 55 func (mc *StaticMetricCollector) setRequestProgressToFalse() { 56 mc.Lock() 57 mc.requestInProgress = false 58 mc.Unlock() 59 } 60 61 // Describe is the implementation of Describe in prometheus.Collector 62 func (mc *StaticMetricCollector) Describe(ch chan<- *prometheus.Desc) { 63 for _, col := range mc.metrics.Collectors() { 64 col.Describe(ch) 65 } 66 } 67 68 // Collect is the implementation of Collect in prometheus.Collector 69 func (mc *StaticMetricCollector) Collect(ch chan<- prometheus.Metric) { 70 71 klog.V(4).Info("Starting to collect metrics for a request") 72 73 // when a second request comes, and the first one is already in progress, 74 // ignore/reject the second request 75 mc.Lock() 76 if mc.requestInProgress { 77 klog.V(4).Info("Another request already in progress.") 78 mc.metrics.IncRejectRequestCounter() 79 mc.Unlock() 80 return 81 } 82 83 mc.requestInProgress = true 84 mc.Unlock() 85 86 // once a request is processed, set the progress flag to false 87 defer mc.setRequestProgressToFalse() 88 89 klog.V(4).Info("Setting client for this request.") 90 91 // set the client each time 92 if err := mc.Client.InitClient(); err != nil { 93 klog.Errorf("error setting client. %v", err) 94 mc.metrics.IncErrorRequestCounter() 95 mc.collectErrors(ch) 96 return 97 } 98 99 // get list of blockdevices from etcd 100 blockDevices, err := mc.Client.ListBlockDevice() 101 if err != nil { 102 mc.metrics.IncErrorRequestCounter() 103 mc.collectErrors(ch) 104 return 105 } 106 107 klog.V(4).Info("Metric data fetched from etcd") 108 109 // set the metric data into the respective fields 110 mc.metrics.SetMetrics(blockDevices) 111 112 klog.V(4).Info("Prometheus metrics is set and initializing collection.") 113 114 // collect each metric 115 for _, col := range mc.metrics.Collectors() { 116 col.Collect(ch) 117 } 118 } 119 120 // collectErrors collects only the error metrics and set it on the channel 121 func (mc *StaticMetricCollector) collectErrors(ch chan<- prometheus.Metric) { 122 for _, col := range mc.metrics.ErrorCollectors() { 123 col.Collect(ch) 124 } 125 }