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 }