github.com/galamsiva2020/kubernetes-heapster-monitoring@v0.0.0-20210823134957-3c1baa7c1e70/metrics/storage/podmetrics/reststorage.go (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package app 16 17 import ( 18 "fmt" 19 "time" 20 21 "github.com/golang/glog" 22 23 "k8s.io/api/core/v1" 24 "k8s.io/apimachinery/pkg/api/errors" 25 metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/labels" 28 "k8s.io/apimachinery/pkg/runtime" 29 "k8s.io/apimachinery/pkg/runtime/schema" 30 genericapirequest "k8s.io/apiserver/pkg/endpoints/request" 31 "k8s.io/apiserver/pkg/registry/rest" 32 v1listers "k8s.io/client-go/listers/core/v1" 33 "k8s.io/heapster/metrics/core" 34 metricsink "k8s.io/heapster/metrics/sinks/metric" 35 "k8s.io/heapster/metrics/storage/util" 36 "k8s.io/metrics/pkg/apis/metrics" 37 _ "k8s.io/metrics/pkg/apis/metrics/install" 38 ) 39 40 type MetricStorage struct { 41 groupResource schema.GroupResource 42 metricSink *metricsink.MetricSink 43 podLister v1listers.PodLister 44 } 45 46 var _ rest.KindProvider = &MetricStorage{} 47 var _ rest.Storage = &MetricStorage{} 48 var _ rest.Getter = &MetricStorage{} 49 var _ rest.Lister = &MetricStorage{} 50 51 func NewStorage(groupResource schema.GroupResource, metricSink *metricsink.MetricSink, podLister v1listers.PodLister) *MetricStorage { 52 return &MetricStorage{ 53 groupResource: groupResource, 54 metricSink: metricSink, 55 podLister: podLister, 56 } 57 } 58 59 // Storage interface 60 func (m *MetricStorage) New() runtime.Object { 61 return &metrics.PodMetrics{} 62 } 63 64 // KindProvider interface 65 func (m *MetricStorage) Kind() string { 66 return "PodMetrics" 67 } 68 69 // Lister interface 70 func (m *MetricStorage) NewList() runtime.Object { 71 return &metrics.PodMetricsList{} 72 } 73 74 // Lister interface 75 func (m *MetricStorage) List(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { 76 labelSelector := labels.Everything() 77 if options != nil && options.LabelSelector != nil { 78 labelSelector = options.LabelSelector 79 } 80 namespace := genericapirequest.NamespaceValue(ctx) 81 pods, err := m.podLister.Pods(namespace).List(labelSelector) 82 if err != nil { 83 errMsg := fmt.Errorf("Error while listing pods for selector %v: %v", labelSelector, err) 84 glog.Error(errMsg) 85 return &metrics.PodMetricsList{}, errMsg 86 } 87 88 res := metrics.PodMetricsList{} 89 for _, pod := range pods { 90 if podMetrics := m.getPodMetrics(pod); podMetrics != nil { 91 res.Items = append(res.Items, *podMetrics) 92 } else { 93 glog.Infof("No metrics for pod %s/%s", pod.Namespace, pod.Name) 94 } 95 } 96 return &res, nil 97 } 98 99 // Getter interface 100 func (m *MetricStorage) Get(ctx genericapirequest.Context, name string, opts *metav1.GetOptions) (runtime.Object, error) { 101 namespace := genericapirequest.NamespaceValue(ctx) 102 103 pod, err := m.podLister.Pods(namespace).Get(name) 104 if err != nil { 105 errMsg := fmt.Errorf("Error while getting pod %v: %v", name, err) 106 glog.Error(errMsg) 107 return &metrics.PodMetrics{}, errMsg 108 } 109 if pod == nil { 110 return &metrics.PodMetrics{}, errors.NewNotFound(v1.Resource("Pod"), fmt.Sprintf("%v/%v", namespace, name)) 111 } 112 113 podMetrics := m.getPodMetrics(pod) 114 if podMetrics == nil { 115 return &metrics.PodMetrics{}, errors.NewNotFound(m.groupResource, fmt.Sprintf("%v/%v", namespace, name)) 116 } 117 return podMetrics, nil 118 } 119 120 func (m *MetricStorage) getPodMetrics(pod *v1.Pod) *metrics.PodMetrics { 121 batch := m.metricSink.GetLatestDataBatch() 122 if batch == nil { 123 return nil 124 } 125 126 res := &metrics.PodMetrics{ 127 ObjectMeta: metav1.ObjectMeta{ 128 Name: pod.Name, 129 Namespace: pod.Namespace, 130 CreationTimestamp: metav1.NewTime(time.Now()), 131 }, 132 Timestamp: metav1.NewTime(batch.Timestamp), 133 Window: metav1.Duration{Duration: time.Minute}, 134 Containers: make([]metrics.ContainerMetrics, 0), 135 } 136 137 for _, c := range pod.Spec.Containers { 138 ms, found := batch.MetricSets[core.PodContainerKey(pod.Namespace, pod.Name, c.Name)] 139 if !found { 140 glog.Infof("No metrics for container %s in pod %s/%s", c.Name, pod.Namespace, pod.Name) 141 return nil 142 } 143 usage, err := util.ParseResourceList(ms) 144 if err != nil { 145 return nil 146 } 147 res.Containers = append(res.Containers, metrics.ContainerMetrics{Name: c.Name, Usage: usage}) 148 } 149 150 return res 151 }