k8s.io/perf-tests/clusterloader2@v0.0.0-20240304094227-64bdb12da87e/pkg/measurement/common/bundle/test_metrics.go (about)

     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 bundle
    18  
    19  import (
    20  	"fmt"
    21  
    22  	goerrors "github.com/go-errors/errors"
    23  	"k8s.io/klog/v2"
    24  	"k8s.io/perf-tests/clusterloader2/pkg/errors"
    25  	"k8s.io/perf-tests/clusterloader2/pkg/measurement"
    26  	"k8s.io/perf-tests/clusterloader2/pkg/util"
    27  )
    28  
    29  const (
    30  	testMetricsMeasurementName = "TestMetrics"
    31  )
    32  
    33  func init() {
    34  	if err := measurement.Register(testMetricsMeasurementName, createTestMetricsMeasurement); err != nil {
    35  		klog.Fatalf("Cannot register %s: %v", testMetricsMeasurementName, err)
    36  	}
    37  }
    38  
    39  func createTestMetricsMeasurement() measurement.Measurement {
    40  	var metrics testMetrics
    41  	var err error
    42  	if metrics.etcdMetrics, err = measurement.CreateMeasurement("EtcdMetrics"); err != nil {
    43  		klog.Errorf("%v: etcdMetrics creation error: %v", metrics, err)
    44  	}
    45  	if metrics.schedulingMetrics, err = measurement.CreateMeasurement("SchedulingMetrics"); err != nil {
    46  		klog.Errorf("%v: schedulingMetrics creation error: %v", metrics, err)
    47  	}
    48  	if metrics.metricsForE2E, err = measurement.CreateMeasurement("MetricsForE2E"); err != nil {
    49  		klog.Errorf("%v: metricsForE2E creation error: %v", metrics, err)
    50  	}
    51  	if metrics.resourceUsageSummary, err = measurement.CreateMeasurement("ResourceUsageSummary"); err != nil {
    52  		klog.Errorf("%v: resourceUsageSummary creation error: %v", metrics, err)
    53  	}
    54  	if metrics.etcdCPUProfile, err = measurement.CreateMeasurement("CPUProfile"); err != nil {
    55  		klog.Errorf("%v: etcdCPUProfile creation error: %v", metrics, err)
    56  	}
    57  	if metrics.etcdMemoryProfile, err = measurement.CreateMeasurement("MemoryProfile"); err != nil {
    58  		klog.Errorf("%v: etcdMemoryProfile creation error: %v", metrics, err)
    59  	}
    60  	if metrics.etcdBlockProfile, err = measurement.CreateMeasurement("BlockProfile"); err != nil {
    61  		klog.Errorf("%v: etcdBlockProfile creation error: %v", metrics, err)
    62  	}
    63  	if metrics.apiserverCPUProfile, err = measurement.CreateMeasurement("CPUProfile"); err != nil {
    64  		klog.Errorf("%v: apiserverCPUProfile creation error: %v", metrics, err)
    65  	}
    66  	if metrics.apiserverMemoryProfile, err = measurement.CreateMeasurement("MemoryProfile"); err != nil {
    67  		klog.Errorf("%v: apiserverMemoryProfile creation error: %v", metrics, err)
    68  	}
    69  	if metrics.apiserverBlockProfile, err = measurement.CreateMeasurement("BlockProfile"); err != nil {
    70  		klog.Errorf("%v: apiserverBlockProfile creation error: %v", metrics, err)
    71  	}
    72  	if metrics.schedulerCPUProfile, err = measurement.CreateMeasurement("CPUProfile"); err != nil {
    73  		klog.Errorf("%v: schedulerCPUProfile creation error: %v", metrics, err)
    74  	}
    75  	if metrics.schedulerMemoryProfile, err = measurement.CreateMeasurement("MemoryProfile"); err != nil {
    76  		klog.Errorf("%v: schedulerMemoryProfile creation error: %v", metrics, err)
    77  	}
    78  	if metrics.schedulerBlockProfile, err = measurement.CreateMeasurement("BlockProfile"); err != nil {
    79  		klog.Errorf("%v: schedulerBlockProfile creation error: %v", metrics, err)
    80  	}
    81  	if metrics.controllerManagerCPUProfile, err = measurement.CreateMeasurement("CPUProfile"); err != nil {
    82  		klog.Errorf("%v: controllerManagerCPUProfile creation error: %v", metrics, err)
    83  	}
    84  	if metrics.controllerManagerMemoryProfile, err = measurement.CreateMeasurement("MemoryProfile"); err != nil {
    85  		klog.Errorf("%v: controllerManagerMemoryProfile creation error: %v", metrics, err)
    86  	}
    87  	if metrics.controllerManagerBlockProfile, err = measurement.CreateMeasurement("BlockProfile"); err != nil {
    88  		klog.Errorf("%v: controllerManagerBlockProfile creation error: %v", metrics, err)
    89  	}
    90  	if metrics.systemPodMetrics, err = measurement.CreateMeasurement("SystemPodMetrics"); err != nil {
    91  		klog.Errorf("%v: systemPodMetrics creation error: %v", metrics, err)
    92  	}
    93  	if metrics.clusterOOMsTracker, err = measurement.CreateMeasurement("ClusterOOMsTracker"); err != nil {
    94  		klog.Errorf("%v: clusterOOMsTracker creation error: %v", metrics, err)
    95  	}
    96  	return &metrics
    97  }
    98  
    99  type testMetrics struct {
   100  	etcdMetrics                    measurement.Measurement
   101  	schedulingMetrics              measurement.Measurement
   102  	metricsForE2E                  measurement.Measurement
   103  	resourceUsageSummary           measurement.Measurement
   104  	etcdCPUProfile                 measurement.Measurement
   105  	etcdMemoryProfile              measurement.Measurement
   106  	etcdBlockProfile               measurement.Measurement
   107  	apiserverCPUProfile            measurement.Measurement
   108  	apiserverMemoryProfile         measurement.Measurement
   109  	apiserverBlockProfile          measurement.Measurement
   110  	schedulerCPUProfile            measurement.Measurement
   111  	schedulerMemoryProfile         measurement.Measurement
   112  	schedulerBlockProfile          measurement.Measurement
   113  	controllerManagerCPUProfile    measurement.Measurement
   114  	controllerManagerMemoryProfile measurement.Measurement
   115  	controllerManagerBlockProfile  measurement.Measurement
   116  	systemPodMetrics               measurement.Measurement
   117  	clusterOOMsTracker             measurement.Measurement
   118  }
   119  
   120  // Execute supports two actions. start - which sets up all metrics.
   121  // stop - which stops all metrics and collects all measurements.
   122  func (t *testMetrics) Execute(config *measurement.Config) ([]measurement.Summary, error) {
   123  	var summaries []measurement.Summary
   124  	errList := errors.NewErrorList()
   125  	action, err := util.GetString(config.Params, "action")
   126  	if err != nil {
   127  		return summaries, err
   128  	}
   129  
   130  	actionStartConfig := createConfig(config, map[string]interface{}{
   131  		"action": "start",
   132  	})
   133  	actionResetConfig := createConfig(config, map[string]interface{}{
   134  		"action": "reset",
   135  	})
   136  	actionGatherConfig := createConfig(config, map[string]interface{}{
   137  		"action": "gather",
   138  	})
   139  	etcdStartConfig := createConfig(config, map[string]interface{}{
   140  		"action":        "start",
   141  		"componentName": "etcd",
   142  	})
   143  	etcdGatherConfig := createConfig(config, map[string]interface{}{
   144  		"action":        "gather",
   145  		"componentName": "etcd",
   146  	})
   147  	kubeApiserverStartConfig := createConfig(config, map[string]interface{}{
   148  		"action":        "start",
   149  		"componentName": "kube-apiserver",
   150  	})
   151  	kubeApiserverGatherConfig := createConfig(config, map[string]interface{}{
   152  		"action":        "gather",
   153  		"componentName": "kube-apiserver",
   154  	})
   155  	kubeSchedulerStartConfig := createConfig(config, map[string]interface{}{
   156  		"action":        "start",
   157  		"componentName": "kube-scheduler",
   158  	})
   159  	kubeSchedulerGatherConfig := createConfig(config, map[string]interface{}{
   160  		"action":        "gather",
   161  		"componentName": "kube-scheduler",
   162  	})
   163  	kubeControllerManagerStartConfig := createConfig(config, map[string]interface{}{
   164  		"action":        "start",
   165  		"componentName": "kube-controller-manager",
   166  	})
   167  	kubeControllerManagerGatherConfig := createConfig(config, map[string]interface{}{
   168  		"action":        "gather",
   169  		"componentName": "kube-controller-manager",
   170  	})
   171  
   172  	switch action {
   173  	case "start":
   174  		summary, err := execute(t.etcdMetrics, actionStartConfig)
   175  		appendResults(&summaries, errList, summary, executeError(t.etcdMetrics.String(), action, err))
   176  		summary, err = execute(t.schedulingMetrics, actionResetConfig)
   177  		appendResults(&summaries, errList, summary, executeError(t.schedulingMetrics.String(), action, err))
   178  		summary, err = execute(t.resourceUsageSummary, actionStartConfig)
   179  		appendResults(&summaries, errList, summary, executeError(t.resourceUsageSummary.String(), action, err))
   180  		summary, err = execute(t.etcdCPUProfile, etcdStartConfig)
   181  		appendResults(&summaries, errList, summary, executeError(t.etcdCPUProfile.String(), action, err))
   182  		summary, err = execute(t.etcdMemoryProfile, etcdStartConfig)
   183  		appendResults(&summaries, errList, summary, executeError(t.etcdMemoryProfile.String(), action, err))
   184  		summary, err = execute(t.etcdBlockProfile, etcdStartConfig)
   185  		appendResults(&summaries, errList, summary, executeError(t.etcdBlockProfile.String(), action, err))
   186  		summary, err = execute(t.apiserverCPUProfile, kubeApiserverStartConfig)
   187  		appendResults(&summaries, errList, summary, executeError(t.apiserverCPUProfile.String(), action, err))
   188  		summary, err = execute(t.apiserverMemoryProfile, kubeApiserverStartConfig)
   189  		appendResults(&summaries, errList, summary, executeError(t.apiserverMemoryProfile.String(), action, err))
   190  		summary, err = execute(t.apiserverBlockProfile, kubeApiserverStartConfig)
   191  		appendResults(&summaries, errList, summary, executeError(t.apiserverBlockProfile.String(), action, err))
   192  		summary, err = execute(t.schedulerCPUProfile, kubeSchedulerStartConfig)
   193  		appendResults(&summaries, errList, summary, executeError(t.schedulerCPUProfile.String(), action, err))
   194  		summary, err = execute(t.schedulerMemoryProfile, kubeSchedulerStartConfig)
   195  		appendResults(&summaries, errList, summary, executeError(t.schedulerMemoryProfile.String(), action, err))
   196  		summary, err = execute(t.schedulerBlockProfile, kubeSchedulerStartConfig)
   197  		appendResults(&summaries, errList, summary, executeError(t.schedulerBlockProfile.String(), action, err))
   198  		summary, err = execute(t.controllerManagerCPUProfile, kubeControllerManagerStartConfig)
   199  		appendResults(&summaries, errList, summary, executeError(t.controllerManagerCPUProfile.String(), action, err))
   200  		summary, err = execute(t.controllerManagerMemoryProfile, kubeControllerManagerStartConfig)
   201  		appendResults(&summaries, errList, summary, executeError(t.controllerManagerMemoryProfile.String(), action, err))
   202  		summary, err = execute(t.controllerManagerBlockProfile, kubeControllerManagerStartConfig)
   203  		appendResults(&summaries, errList, summary, executeError(t.controllerManagerBlockProfile.String(), action, err))
   204  		summary, err = execute(t.systemPodMetrics, config)
   205  		appendResults(&summaries, errList, summary, executeError(t.systemPodMetrics.String(), action, err))
   206  		summary, err = execute(t.clusterOOMsTracker, config)
   207  		appendResults(&summaries, errList, summary, executeError(t.clusterOOMsTracker.String(), action, err))
   208  	case "gather":
   209  		summary, err := execute(t.etcdMetrics, actionGatherConfig)
   210  		appendResults(&summaries, errList, summary, executeError(t.etcdMetrics.String(), action, err))
   211  		summary, err = execute(t.schedulingMetrics, actionGatherConfig)
   212  		appendResults(&summaries, errList, summary, executeError(t.schedulingMetrics.String(), action, err))
   213  		summary, err = execute(t.metricsForE2E, config)
   214  		appendResults(&summaries, errList, summary, executeError(t.metricsForE2E.String(), action, err))
   215  		summary, err = execute(t.resourceUsageSummary, actionGatherConfig)
   216  		appendResults(&summaries, errList, summary, executeError(t.resourceUsageSummary.String(), action, err))
   217  		summary, err = execute(t.etcdCPUProfile, etcdGatherConfig)
   218  		appendResults(&summaries, errList, summary, executeError(t.etcdCPUProfile.String(), action, err))
   219  		summary, err = execute(t.etcdMemoryProfile, etcdGatherConfig)
   220  		appendResults(&summaries, errList, summary, executeError(t.etcdMemoryProfile.String(), action, err))
   221  		summary, err = execute(t.etcdBlockProfile, etcdGatherConfig)
   222  		appendResults(&summaries, errList, summary, executeError(t.etcdBlockProfile.String(), action, err))
   223  		summary, err = execute(t.apiserverCPUProfile, kubeApiserverGatherConfig)
   224  		appendResults(&summaries, errList, summary, executeError(t.apiserverCPUProfile.String(), action, err))
   225  		summary, err = execute(t.apiserverMemoryProfile, kubeApiserverGatherConfig)
   226  		appendResults(&summaries, errList, summary, executeError(t.apiserverMemoryProfile.String(), action, err))
   227  		summary, err = execute(t.apiserverBlockProfile, kubeApiserverGatherConfig)
   228  		appendResults(&summaries, errList, summary, executeError(t.apiserverBlockProfile.String(), action, err))
   229  		summary, err = execute(t.schedulerCPUProfile, kubeSchedulerGatherConfig)
   230  		appendResults(&summaries, errList, summary, executeError(t.schedulerCPUProfile.String(), action, err))
   231  		summary, err = execute(t.schedulerMemoryProfile, kubeSchedulerGatherConfig)
   232  		appendResults(&summaries, errList, summary, executeError(t.schedulerMemoryProfile.String(), action, err))
   233  		summary, err = execute(t.schedulerBlockProfile, kubeSchedulerGatherConfig)
   234  		appendResults(&summaries, errList, summary, executeError(t.schedulerBlockProfile.String(), action, err))
   235  		summary, err = execute(t.controllerManagerCPUProfile, kubeControllerManagerGatherConfig)
   236  		appendResults(&summaries, errList, summary, executeError(t.controllerManagerCPUProfile.String(), action, err))
   237  		summary, err = execute(t.controllerManagerMemoryProfile, kubeControllerManagerGatherConfig)
   238  		appendResults(&summaries, errList, summary, executeError(t.controllerManagerMemoryProfile.String(), action, err))
   239  		summary, err = execute(t.controllerManagerBlockProfile, kubeControllerManagerGatherConfig)
   240  		appendResults(&summaries, errList, summary, executeError(t.controllerManagerBlockProfile.String(), action, err))
   241  		summary, err = execute(t.systemPodMetrics, config)
   242  		appendResults(&summaries, errList, summary, executeError(t.systemPodMetrics.String(), action, err))
   243  		summary, err = execute(t.clusterOOMsTracker, config)
   244  		appendResults(&summaries, errList, summary, executeError(t.clusterOOMsTracker.String(), action, err))
   245  	default:
   246  		return summaries, fmt.Errorf("unknown action %v", action)
   247  	}
   248  
   249  	if !errList.IsEmpty() {
   250  		klog.Errorf("%s: %v", t, errList.String())
   251  		return summaries, errList
   252  	}
   253  	return summaries, nil
   254  }
   255  
   256  // Dispose cleans up after the measurement.
   257  func (t *testMetrics) Dispose() {
   258  	t.etcdMetrics.Dispose()
   259  	t.schedulingMetrics.Dispose()
   260  	t.metricsForE2E.Dispose()
   261  	t.resourceUsageSummary.Dispose()
   262  	t.etcdCPUProfile.Dispose()
   263  	t.etcdMemoryProfile.Dispose()
   264  	t.etcdBlockProfile.Dispose()
   265  	t.apiserverCPUProfile.Dispose()
   266  	t.apiserverMemoryProfile.Dispose()
   267  	t.apiserverBlockProfile.Dispose()
   268  	t.schedulerCPUProfile.Dispose()
   269  	t.schedulerMemoryProfile.Dispose()
   270  	t.schedulerBlockProfile.Dispose()
   271  	t.controllerManagerCPUProfile.Dispose()
   272  	t.controllerManagerMemoryProfile.Dispose()
   273  	t.controllerManagerBlockProfile.Dispose()
   274  }
   275  
   276  // String returns a string representation of the measurement.
   277  func (*testMetrics) String() string {
   278  	return testMetricsMeasurementName
   279  }
   280  
   281  func createConfig(config *measurement.Config, overrides map[string]interface{}) *measurement.Config {
   282  	params := make(map[string]interface{})
   283  	for k, v := range config.Params {
   284  		params[k] = v
   285  	}
   286  	for k, v := range overrides {
   287  		params[k] = v
   288  	}
   289  	return &measurement.Config{
   290  		ClusterFramework:    config.ClusterFramework,
   291  		PrometheusFramework: config.PrometheusFramework,
   292  		Params:              params,
   293  		TemplateProvider:    config.TemplateProvider,
   294  		CloudProvider:       config.CloudProvider,
   295  	}
   296  }
   297  
   298  func execute(m measurement.Measurement, config *measurement.Config) ([]measurement.Summary, error) {
   299  	if m == nil {
   300  		return nil, fmt.Errorf("uninitialized metric")
   301  	}
   302  	return m.Execute(config)
   303  }
   304  
   305  func appendResults(summaries *[]measurement.Summary, errList *errors.ErrorList, summaryResults []measurement.Summary, errResult error) {
   306  	if errResult != nil {
   307  		errList.Append(errResult)
   308  	}
   309  	*summaries = append(*summaries, summaryResults...)
   310  }
   311  
   312  func executeError(measurement, action string, err error) error {
   313  	if err != nil {
   314  		return goerrors.Errorf("action %s failed for %s measurement: %v", action, measurement, err)
   315  	}
   316  	return nil
   317  }