github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/pkg/test/framework/metrics/prometheus.go (about) 1 // Copyright (c) 2021, 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package metrics 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/prometheus/client_golang/prometheus" 11 "github.com/prometheus/client_golang/prometheus/push" 12 "github.com/verrazzano/verrazzano/tests/e2e/pkg" 13 ) 14 15 type PrometheusMetricsReceiverConfig struct { 16 PushGatewayURL string 17 PushGatewayUser string 18 PushGatewayPassword string 19 PushInterval time.Duration 20 Name string 21 } 22 23 type PrometheusMetricsReceiver struct { 24 promPusher *push.Pusher 25 Name string 26 counters map[string]prometheus.Counter 27 gauges map[string]prometheus.Gauge 28 } 29 30 func (pcfg *PrometheusMetricsReceiverConfig) GetReceiverType() string { 31 return "PrometheusMetricsReceiver" 32 } 33 34 func (rcvr *PrometheusMetricsReceiver) SetGauge(name string, value float64) error { 35 if rcvr.gauges == nil { 36 rcvr.gauges = make(map[string]prometheus.Gauge) 37 } 38 metricName := rcvr.makeMetricName(name) 39 gauge := rcvr.gauges[metricName] 40 if gauge == nil { 41 gauge = prometheus.NewGauge(prometheus.GaugeOpts{Name: metricName}) 42 rcvr.gauges[metricName] = gauge 43 } 44 gauge.Set(value) 45 pkg.Log(pkg.Info, fmt.Sprintf("Emitting gauge %s with value %f", metricName, value)) 46 47 // Asynchronously push the gauge to the Prometheus push gateway 48 rcvr.asyncPush(gauge, metricName) 49 return nil 50 } 51 52 func (rcvr *PrometheusMetricsReceiver) IncrementCounter(name string) error { 53 if rcvr.counters == nil { 54 rcvr.counters = make(map[string]prometheus.Counter) 55 } 56 metricName := rcvr.makeMetricName(name) 57 ctr := rcvr.counters[metricName] 58 if ctr == nil { 59 ctr = prometheus.NewCounter(prometheus.CounterOpts{Name: metricName}) 60 rcvr.counters[metricName] = ctr 61 } 62 ctr.Inc() 63 pkg.Log(pkg.Info, fmt.Sprintf("Incrementing counter %s", metricName)) 64 65 rcvr.asyncPush(ctr, metricName) 66 return nil 67 } 68 69 // Use a goroutine to asynchronously kick off a push to the Prometheus gateway represented by rcvr.promPusher 70 func (rcvr *PrometheusMetricsReceiver) asyncPush(ctr prometheus.Collector, metricName string) { 71 go func() { 72 // push the counter to the gateway 73 if err := rcvr.promPusher.Collector(ctr).Add(); err != nil { 74 pkg.Log(pkg.Error, fmt.Sprintf("could not push metric %s to push gateway: %s", metricName, err.Error())) 75 } 76 pkg.Log(pkg.Info, fmt.Sprintf("Successfully emitted metric %s", metricName)) 77 }() 78 } 79 80 // Create a new PrometheusMetricsReceiver based on the configuration options provided 81 func NewPrometheusMetricsReceiver(cfg PrometheusMetricsReceiverConfig) (*PrometheusMetricsReceiver, error) { 82 receiver := PrometheusMetricsReceiver{} 83 pusher := push.New(cfg.PushGatewayURL, cfg.Name) 84 if cfg.PushGatewayUser != "" && cfg.PushGatewayPassword != "" { 85 pusher = pusher.BasicAuth(cfg.PushGatewayUser, cfg.PushGatewayPassword) 86 } 87 receiver.promPusher = pusher 88 receiver.Name = cfg.Name 89 return &receiver, nil 90 } 91 92 func (rcvr *PrometheusMetricsReceiver) makeMetricName(name string) string { 93 if rcvr.Name != "" { 94 return rcvr.Name + "_" + name 95 } 96 return name 97 }