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

     1  /*
     2  Copyright 2020 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 slos
    18  
    19  import (
    20  	"math"
    21  	"time"
    22  
    23  	"github.com/prometheus/common/model"
    24  	"k8s.io/klog/v2"
    25  	"k8s.io/perf-tests/clusterloader2/pkg/measurement"
    26  	"k8s.io/perf-tests/clusterloader2/pkg/measurement/common"
    27  	measurementutil "k8s.io/perf-tests/clusterloader2/pkg/measurement/util"
    28  	"k8s.io/perf-tests/clusterloader2/pkg/util"
    29  )
    30  
    31  const (
    32  	windowsResourceUsagePrometheusMeasurementName = "WindowsResourceUsagePrometheus"
    33  	// get top 10 non-system processes with highest cpu usage within 1min query window size
    34  	cpuUsageQueryTop10 = `topk(10, sum by (process) (irate(windows_process_cpu_time_total{process!~"Idle|Total|System"}[5m]) / on(job) group_left windows_cs_logical_processors) * 100)`
    35  	// cpu usage metrics file name prefix
    36  	cpuUsageMetricsName = "WindowsCPUUsagePrometheus"
    37  	// get top 10 non-system processes with highest memory usage
    38  	memoryUsageQueryTop10 = `topk(10, sum(windows_process_working_set_bytes{process!~"Idle|Total|System"}) by (process))`
    39  	// memory usage metrics file name prefix
    40  	memoryUsageMetricsName = "WindowsMemoryUsagePrometheus"
    41  	// get the total disk size by volume
    42  	nodeStorageUsageQuery = `sum(windows_logical_disk_size_bytes) by (volume)`
    43  	// node storage usage file name prefix
    44  	nodeStorageUsageMetricsName = "WindowsNodeStorage"
    45  	// get the total open file descriptors
    46  	openFilesQuery = `sum(process_open_fds{service="windows-exporter"})`
    47  	// open files metrics file name prefix
    48  	openFilesMetricsName = "WindowsOpenFiles"
    49  	// bytes issued to I/O operations
    50  	processQueryTop10 = `topk(10, sum by (process) (windows_process_io_bytes_total{process!~"Idle|Total|System"}))`
    51  	// process metrics file name prefix
    52  	processMetricsName = "WindowsProcesses"
    53  	// number of Windows containers
    54  	containerQueryTop10 = `topk(10, sum by (instance) (windows_container_count))`
    55  	// container metrics file name prefix
    56  	containerMetricsName = "WindowsContainers"
    57  	// total bytes received and transmitted by interface
    58  	networkQueryTop10 = `topk(10, sum by (nic) (windows_net_bytes_total))`
    59  	// network metrics file name prefix
    60  	networkMetricsName                        = "WindowsNetwork"
    61  	currentWindowsResourceUsageMetricsVersion = "v1"
    62  )
    63  
    64  type convertFunc func([]*model.Sample) *measurementutil.PerfData
    65  type windowsResourceUsageGatherer struct{}
    66  
    67  func (w *windowsResourceUsageGatherer) Configure(config *measurement.Config) error {
    68  	return nil
    69  }
    70  
    71  func (w *windowsResourceUsageGatherer) IsEnabled(config *measurement.Config) bool {
    72  	return true
    73  }
    74  
    75  func (w *windowsResourceUsageGatherer) String() string {
    76  	return windowsResourceUsagePrometheusMeasurementName
    77  }
    78  
    79  func init() {
    80  	create := func() measurement.Measurement {
    81  		return common.CreatePrometheusMeasurement(&windowsResourceUsageGatherer{})
    82  	}
    83  	if err := measurement.Register(windowsResourceUsagePrometheusMeasurementName, create); err != nil {
    84  		klog.Fatalf("Cannot register %s: %v", windowsResourceUsagePrometheusMeasurementName, err)
    85  	}
    86  }
    87  
    88  func convertToCPUPerfData(samples []*model.Sample) *measurementutil.PerfData {
    89  	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
    90  	for _, sample := range samples {
    91  		item := measurementutil.DataItem{
    92  			Data: map[string]float64{
    93  				"CPU_Usage": math.Round(float64(sample.Value)*100) / 100,
    94  			},
    95  			Unit: "%",
    96  			Labels: map[string]string{
    97  				"Process": string(sample.Metric["process"]),
    98  			},
    99  		}
   100  		perfData.DataItems = append(perfData.DataItems, item)
   101  	}
   102  	return perfData
   103  }
   104  
   105  func convertToMemoryPerfData(samples []*model.Sample) *measurementutil.PerfData {
   106  	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
   107  	for _, sample := range samples {
   108  		item := measurementutil.DataItem{
   109  			Data: map[string]float64{
   110  				"Memory_Usage": math.Round(float64(sample.Value)*100/(1024*1024)) / 100,
   111  			},
   112  			Unit: "MB",
   113  			Labels: map[string]string{
   114  				"Process": string(sample.Metric["process"]),
   115  			},
   116  		}
   117  		perfData.DataItems = append(perfData.DataItems, item)
   118  	}
   119  	return perfData
   120  }
   121  
   122  func convertToStoragePerfData(samples []*model.Sample) *measurementutil.PerfData {
   123  	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
   124  	for _, sample := range samples {
   125  		item := measurementutil.DataItem{
   126  			Data: map[string]float64{
   127  				"Storage_Used": math.Round(float64(sample.Value)*100/(1024*1024*1024)) / 100,
   128  			},
   129  			Unit: "GB",
   130  			Labels: map[string]string{
   131  				"Volume": string(sample.Metric["volume"]),
   132  			},
   133  		}
   134  		perfData.DataItems = append(perfData.DataItems, item)
   135  	}
   136  	return perfData
   137  }
   138  
   139  func convertToOpenFilesPerfData(samples []*model.Sample) *measurementutil.PerfData {
   140  	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
   141  	for _, sample := range samples {
   142  		item := measurementutil.DataItem{
   143  			Data: map[string]float64{
   144  				"Open File Handles": math.Round(float64(sample.Value)),
   145  			},
   146  			Unit: "Handles",
   147  			Labels: map[string]string{
   148  				"Job": string(sample.Metric["job"]),
   149  			},
   150  		}
   151  		perfData.DataItems = append(perfData.DataItems, item)
   152  	}
   153  	return perfData
   154  }
   155  
   156  func convertToProcessPerfData(samples []*model.Sample) *measurementutil.PerfData {
   157  	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
   158  	for _, sample := range samples {
   159  		item := measurementutil.DataItem{
   160  			Data: map[string]float64{
   161  				"Process Handles": math.Round(float64(sample.Value)*100) / 100,
   162  			},
   163  			Unit: "Handles",
   164  			Labels: map[string]string{
   165  				"Process": string(sample.Metric["process"]),
   166  			},
   167  		}
   168  		perfData.DataItems = append(perfData.DataItems, item)
   169  	}
   170  	return perfData
   171  }
   172  
   173  func convertToNetworkPerfData(samples []*model.Sample) *measurementutil.PerfData {
   174  	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
   175  	for _, sample := range samples {
   176  		item := measurementutil.DataItem{
   177  			Data: map[string]float64{
   178  				"Network_Bytes_Total": math.Round(float64(sample.Value)*100/(1024*1024)) / 100,
   179  			},
   180  			Unit: "MB",
   181  			Labels: map[string]string{
   182  				"NIC": string(sample.Metric["nic"]),
   183  			},
   184  		}
   185  		perfData.DataItems = append(perfData.DataItems, item)
   186  	}
   187  	return perfData
   188  }
   189  
   190  func convertToContainerPerfData(samples []*model.Sample) *measurementutil.PerfData {
   191  	perfData := &measurementutil.PerfData{Version: currentWindowsResourceUsageMetricsVersion}
   192  	for _, sample := range samples {
   193  		item := measurementutil.DataItem{
   194  			Data: map[string]float64{
   195  				"Windows Container Count": math.Round(float64(sample.Value)*100/(1024*1024)) / 100,
   196  			},
   197  			Unit: "Containers",
   198  			Labels: map[string]string{
   199  				"Instance": string(sample.Metric["instance"]),
   200  			},
   201  		}
   202  		perfData.DataItems = append(perfData.DataItems, item)
   203  	}
   204  	return perfData
   205  }
   206  func getSummary(query string, converter convertFunc, metricsName string, measurementTime time.Time, executor common.QueryExecutor, config *measurement.Config) (measurement.Summary, error) {
   207  	samples, err := executor.Query(query, measurementTime)
   208  	if err != nil {
   209  		return nil, err
   210  	}
   211  	content, err := util.PrettyPrintJSON(converter(samples))
   212  	if err != nil {
   213  		return nil, err
   214  	}
   215  	summaryName, err := util.GetStringOrDefault(config.Params, "summaryName", metricsName)
   216  	if err != nil {
   217  		return nil, err
   218  	}
   219  	return measurement.CreateSummary(summaryName, "json", content), nil
   220  }
   221  
   222  // Gather gathers the metrics and convert to json summary
   223  func (w *windowsResourceUsageGatherer) Gather(executor common.QueryExecutor, startTime, endTime time.Time, config *measurement.Config) ([]measurement.Summary, error) {
   224  	cpuSummary, err := getSummary(cpuUsageQueryTop10, convertToCPUPerfData, cpuUsageMetricsName, endTime, executor, config)
   225  	if err != nil {
   226  		return nil, err
   227  	}
   228  	memorySummary, err := getSummary(memoryUsageQueryTop10, convertToMemoryPerfData, memoryUsageMetricsName, endTime, executor, config)
   229  	if err != nil {
   230  		return nil, err
   231  	}
   232  	nodeStorageSummary, err := getSummary(nodeStorageUsageQuery, convertToStoragePerfData, nodeStorageUsageMetricsName, endTime, executor, config)
   233  	if err != nil {
   234  		return nil, err
   235  	}
   236  	openFilesSummary, err := getSummary(openFilesQuery, convertToOpenFilesPerfData, openFilesMetricsName, endTime, executor, config)
   237  	if err != nil {
   238  		return nil, err
   239  	}
   240  	processSummary, err := getSummary(processQueryTop10, convertToProcessPerfData, processMetricsName, endTime, executor, config)
   241  	if err != nil {
   242  		return nil, err
   243  	}
   244  	networkSummary, err := getSummary(networkQueryTop10, convertToNetworkPerfData, networkMetricsName, endTime, executor, config)
   245  	if err != nil {
   246  		return nil, err
   247  	}
   248  	containerSummary, err := getSummary(containerQueryTop10, convertToContainerPerfData, containerMetricsName, endTime, executor, config)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	return []measurement.Summary{cpuSummary, memorySummary, nodeStorageSummary, openFilesSummary, processSummary, networkSummary, containerSummary}, nil
   253  }