k8s.io/kubernetes@v1.29.3/test/e2e/framework/metrics/e2e_metrics.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 metrics
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/json"
    22  	"fmt"
    23  
    24  	"k8s.io/component-base/metrics/testutil"
    25  	"k8s.io/kubernetes/test/e2e/framework"
    26  )
    27  
    28  const (
    29  	// Cluster Autoscaler metrics names
    30  	caFunctionMetric      = "cluster_autoscaler_function_duration_seconds_bucket"
    31  	caFunctionMetricLabel = "function"
    32  )
    33  
    34  // ComponentCollection is metrics collection of components.
    35  type ComponentCollection Collection
    36  
    37  func (m *ComponentCollection) filterMetrics() {
    38  	apiServerMetrics := make(APIServerMetrics)
    39  	for _, metric := range interestingAPIServerMetrics {
    40  		apiServerMetrics[metric] = (*m).APIServerMetrics[metric]
    41  	}
    42  	controllerManagerMetrics := make(ControllerManagerMetrics)
    43  	for _, metric := range interestingControllerManagerMetrics {
    44  		controllerManagerMetrics[metric] = (*m).ControllerManagerMetrics[metric]
    45  	}
    46  	kubeletMetrics := make(map[string]KubeletMetrics)
    47  	for kubelet, grabbed := range (*m).KubeletMetrics {
    48  		kubeletMetrics[kubelet] = make(KubeletMetrics)
    49  		for _, metric := range interestingKubeletMetrics {
    50  			kubeletMetrics[kubelet][metric] = grabbed[metric]
    51  		}
    52  	}
    53  	(*m).APIServerMetrics = apiServerMetrics
    54  	(*m).ControllerManagerMetrics = controllerManagerMetrics
    55  	(*m).KubeletMetrics = kubeletMetrics
    56  }
    57  
    58  // PrintHumanReadable returns e2e metrics with JSON format.
    59  func (m *ComponentCollection) PrintHumanReadable() string {
    60  	buf := bytes.Buffer{}
    61  	for _, interestingMetric := range interestingAPIServerMetrics {
    62  		buf.WriteString(fmt.Sprintf("For %v:\n", interestingMetric))
    63  		for _, sample := range (*m).APIServerMetrics[interestingMetric] {
    64  			buf.WriteString(fmt.Sprintf("\t%v\n", testutil.PrintSample(sample)))
    65  		}
    66  	}
    67  	for _, interestingMetric := range interestingControllerManagerMetrics {
    68  		buf.WriteString(fmt.Sprintf("For %v:\n", interestingMetric))
    69  		for _, sample := range (*m).ControllerManagerMetrics[interestingMetric] {
    70  			buf.WriteString(fmt.Sprintf("\t%v\n", testutil.PrintSample(sample)))
    71  		}
    72  	}
    73  	for _, interestingMetric := range interestingClusterAutoscalerMetrics {
    74  		buf.WriteString(fmt.Sprintf("For %v:\n", interestingMetric))
    75  		for _, sample := range (*m).ClusterAutoscalerMetrics[interestingMetric] {
    76  			buf.WriteString(fmt.Sprintf("\t%v\n", testutil.PrintSample(sample)))
    77  		}
    78  	}
    79  	for kubelet, grabbed := range (*m).KubeletMetrics {
    80  		buf.WriteString(fmt.Sprintf("For %v:\n", kubelet))
    81  		for _, interestingMetric := range interestingKubeletMetrics {
    82  			buf.WriteString(fmt.Sprintf("\tFor %v:\n", interestingMetric))
    83  			for _, sample := range grabbed[interestingMetric] {
    84  				buf.WriteString(fmt.Sprintf("\t\t%v\n", testutil.PrintSample(sample)))
    85  			}
    86  		}
    87  	}
    88  	return buf.String()
    89  }
    90  
    91  // PrettyPrintJSON converts metrics to JSON format.
    92  // TODO: This function should be replaced with framework.PrettyPrintJSON after solving
    93  // circulary dependency between core framework and this metrics subpackage.
    94  func PrettyPrintJSON(metrics interface{}) string {
    95  	output := &bytes.Buffer{}
    96  	if err := json.NewEncoder(output).Encode(metrics); err != nil {
    97  		framework.Logf("Error building encoder: %v", err)
    98  		return ""
    99  	}
   100  	formatted := &bytes.Buffer{}
   101  	if err := json.Indent(formatted, output.Bytes(), "", "  "); err != nil {
   102  		framework.Logf("Error indenting: %v", err)
   103  		return ""
   104  	}
   105  	return string(formatted.Bytes())
   106  }
   107  
   108  // PrintJSON returns e2e metrics with JSON format.
   109  func (m *ComponentCollection) PrintJSON() string {
   110  	m.filterMetrics()
   111  	return PrettyPrintJSON(m)
   112  }
   113  
   114  // SummaryKind returns the summary of e2e metrics.
   115  func (m *ComponentCollection) SummaryKind() string {
   116  	return "ComponentCollection"
   117  }
   118  
   119  // ComputeClusterAutoscalerMetricsDelta computes the change in cluster
   120  // autoscaler metrics.
   121  func (m *ComponentCollection) ComputeClusterAutoscalerMetricsDelta(before Collection) {
   122  	if beforeSamples, found := before.ClusterAutoscalerMetrics[caFunctionMetric]; found {
   123  		if afterSamples, found := m.ClusterAutoscalerMetrics[caFunctionMetric]; found {
   124  			testutil.ComputeHistogramDelta(beforeSamples, afterSamples, caFunctionMetricLabel)
   125  		}
   126  	}
   127  }