github.com/kubewharf/katalyst-core@v0.5.3/pkg/util/metric/store_util.go (about) 1 /* 2 Copyright 2022 The Katalyst 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 metric 18 19 import ( 20 "time" 21 22 v1 "k8s.io/api/core/v1" 23 "k8s.io/apimachinery/pkg/util/sets" 24 "k8s.io/klog/v2" 25 26 "github.com/kubewharf/katalyst-core/pkg/util/general" 27 "github.com/kubewharf/katalyst-core/pkg/util/machine" 28 ) 29 30 type Aggregator string 31 32 const ( 33 AggregatorSum Aggregator = "sum" 34 AggregatorAvg Aggregator = "avg" 35 ) 36 37 // ContainerMetricFilter is used to filter out unnecessary metrics if this function returns false 38 type ContainerMetricFilter func(pod *v1.Pod, container *v1.Container) bool 39 40 var DefaultContainerMetricFilter = func(_ *v1.Pod, _ *v1.Container) bool { return true } 41 42 // AggregatePodNumaMetric handles numa-level metric for all pods 43 func (c *MetricStore) AggregatePodNumaMetric(podList []*v1.Pod, numa, metricName string, agg Aggregator, filter ContainerMetricFilter) MetricData { 44 now := time.Now() 45 data := MetricData{Value: .0, Time: &now} 46 47 validPods := sets.NewString() 48 for _, pod := range podList { 49 if validPods.Has(string(pod.UID)) { 50 continue 51 } 52 53 for _, container := range pod.Spec.Containers { 54 if !filter(pod, &container) { 55 continue 56 } 57 58 metric, err := c.GetContainerNumaMetric(string(pod.UID), container.Name, numa, metricName) 59 if err != nil { 60 klog.Errorf("failed to get numa-metric pod %v, container %v, numa %v, metric %v, err: %v", 61 pod.Name, container.Name, numa, metricName, err) 62 continue 63 } 64 validPods.Insert(string(pod.UID)) 65 66 data.Value += metric.Value 67 data.Time = general.MaxTimePtr(data.Time, metric.Time) 68 } 69 } 70 71 switch agg { 72 case AggregatorAvg: 73 if validPods.Len() > 0 { 74 data.Value /= float64(validPods.Len()) 75 } 76 } 77 return data 78 } 79 80 // AggregatePodMetric handles metric for all pods 81 func (c *MetricStore) AggregatePodMetric(podList []*v1.Pod, metricName string, agg Aggregator, filter ContainerMetricFilter) MetricData { 82 now := time.Now() 83 data := MetricData{Value: .0, Time: &now} 84 85 validPods := sets.NewString() 86 for _, pod := range podList { 87 if validPods.Has(string(pod.UID)) { 88 continue 89 } 90 91 for _, container := range pod.Spec.Containers { 92 if !filter(pod, &container) { 93 continue 94 } 95 96 metric, err := c.GetContainerMetric(string(pod.UID), container.Name, metricName) 97 if err != nil { 98 klog.Errorf("failed to get metric pod %v, container %v, metric %v, err: %v", 99 pod.Name, container.Name, metricName, err) 100 continue 101 } 102 validPods.Insert(string(pod.UID)) 103 104 data.Value += metric.Value 105 data.Time = general.MaxTimePtr(data.Time, metric.Time) 106 } 107 } 108 109 switch agg { 110 case AggregatorAvg: 111 if validPods.Len() > 0 { 112 data.Value /= float64(validPods.Len()) 113 } 114 } 115 return data 116 } 117 118 // AggregateCoreMetric handles metric for all cores 119 func (c *MetricStore) AggregateCoreMetric(cpuset machine.CPUSet, metricName string, agg Aggregator) MetricData { 120 now := time.Now() 121 data := MetricData{Value: .0, Time: &now} 122 123 coreCount := 0. 124 for _, cpu := range cpuset.ToSliceInt() { 125 metric, err := c.GetCPUMetric(cpu, metricName) 126 if err != nil { 127 klog.V(4).Infof("failed to get metric cpu %v, metric %v, err: %v", cpu, metricName, err) 128 continue 129 } 130 131 coreCount++ 132 data.Value += metric.Value 133 data.Time = general.MaxTimePtr(data.Time, metric.Time) 134 } 135 136 switch agg { 137 case AggregatorAvg: 138 if coreCount > 0 { 139 data.Value /= coreCount 140 } 141 } 142 return data 143 }