k8s.io/perf-tests/clusterloader2@v0.0.0-20240304094227-64bdb12da87e/pkg/measurement/common/prometheus_measurement.go (about) 1 /* 2 Copyright 2019 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 common 18 19 import ( 20 "fmt" 21 "time" 22 23 "github.com/prometheus/common/model" 24 "k8s.io/klog/v2" 25 "k8s.io/perf-tests/clusterloader2/pkg/errors" 26 "k8s.io/perf-tests/clusterloader2/pkg/measurement" 27 measurementutil "k8s.io/perf-tests/clusterloader2/pkg/measurement/util" 28 prom "k8s.io/perf-tests/clusterloader2/pkg/prometheus/clients" 29 "k8s.io/perf-tests/clusterloader2/pkg/util" 30 ) 31 32 func CreatePrometheusMeasurement(gatherer Gatherer) measurement.Measurement { 33 return &prometheusMeasurement{ 34 gatherer: gatherer, 35 } 36 } 37 38 // QueryExecutor is an interface for queryning Prometheus server. 39 type QueryExecutor interface { 40 Query(query string, queryTime time.Time) ([]*model.Sample, error) 41 } 42 43 // Gatherer is an interface for measurements based on Prometheus metrics. Those measurments don't require any preparation. 44 // It's assumed Prometheus is up, running and instructed to scrape required metrics in the test cluster 45 // (please see clusterloader2/pkg/prometheus/manifests). 46 type Gatherer interface { 47 Configure(config *measurement.Config) error 48 Gather(executor QueryExecutor, startTime, endTime time.Time, config *measurement.Config) ([]measurement.Summary, error) 49 IsEnabled(config *measurement.Config) bool 50 String() string 51 } 52 53 type prometheusMeasurement struct { 54 gatherer Gatherer 55 56 startTime time.Time 57 } 58 59 func (m *prometheusMeasurement) Execute(config *measurement.Config) ([]measurement.Summary, error) { 60 prometheusClient, err := util.GetStringOrDefault(config.Params, "prometheusClient", "inCluster") 61 if err != nil { 62 return nil, err 63 } 64 if prometheusClient != "inCluster" && prometheusClient != "managed" { 65 return nil, fmt.Errorf("unknown Prometheus client") 66 } 67 if prometheusClient == "inCluster" && config.PrometheusFramework == nil { 68 klog.Warningf("%s: Prometheus is disabled, skipping the measurement!", config.Identifier) 69 return nil, nil 70 } 71 72 if !m.gatherer.IsEnabled(config) { 73 klog.Warningf("%s: disabled, skipping the measuerment!", config.Identifier) 74 return nil, nil 75 } 76 77 action, err := util.GetString(config.Params, "action") 78 if err != nil { 79 return nil, err 80 } 81 82 switch action { 83 case "start": 84 if err := m.gatherer.Configure(config); err != nil { 85 return nil, err 86 } 87 klog.V(2).Infof("%s has started", config.Identifier) 88 m.startTime = time.Now() 89 return nil, nil 90 case "gather": 91 klog.V(2).Infof("%s gathering results", config.Identifier) 92 enableViolations, err := util.GetBoolOrDefault(config.Params, "enableViolations", false) 93 if err != nil { 94 return nil, err 95 } 96 97 var pc prom.Client 98 switch prometheusClient { 99 case "inCluster": 100 pc = prom.NewInClusterPrometheusClient(config.PrometheusFramework.GetClientSets().GetClient()) 101 case "managed": 102 pc, err = config.CloudProvider.GetManagedPrometheusClient() 103 if err != nil { 104 return nil, fmt.Errorf("error while creating managed Prometheus client: %w", err) 105 } 106 } 107 executor := measurementutil.NewQueryExecutor(pc) 108 109 summary, err := m.gatherer.Gather(executor, m.startTime, time.Now(), config) 110 if err != nil { 111 if !errors.IsMetricViolationError(err) { 112 klog.Errorf("%s gathering error: %v", config.Identifier, err) 113 return nil, err 114 } 115 if !enableViolations { 116 err = nil 117 } 118 } 119 return summary, err 120 default: 121 return nil, fmt.Errorf("unknown action: %v", action) 122 } 123 } 124 125 func (m *prometheusMeasurement) Dispose() {} 126 127 func (m *prometheusMeasurement) String() string { 128 return m.gatherer.String() 129 }