github.com/jonaz/heapster@v1.3.0-beta.0.0.20170208112634-cd3c15ca3d29/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/heapster/metrics/apis/metrics" 24 _ "k8s.io/heapster/metrics/apis/metrics/install" 25 "k8s.io/heapster/metrics/core" 26 metricsink "k8s.io/heapster/metrics/sinks/metric" 27 "k8s.io/heapster/metrics/storage/util" 28 "k8s.io/kubernetes/pkg/api" 29 "k8s.io/kubernetes/pkg/api/errors" 30 "k8s.io/kubernetes/pkg/api/unversioned" 31 "k8s.io/kubernetes/pkg/client/cache" 32 "k8s.io/kubernetes/pkg/labels" 33 "k8s.io/kubernetes/pkg/runtime" 34 ) 35 36 type MetricStorage struct { 37 groupResource unversioned.GroupResource 38 metricSink *metricsink.MetricSink 39 podLister *cache.StoreToPodLister 40 } 41 42 func NewStorage(groupResource unversioned.GroupResource, metricSink *metricsink.MetricSink, podLister *cache.StoreToPodLister) *MetricStorage { 43 return &MetricStorage{ 44 groupResource: groupResource, 45 metricSink: metricSink, 46 podLister: podLister, 47 } 48 } 49 50 // Storage interface 51 func (m *MetricStorage) New() runtime.Object { 52 return &metrics.PodMetrics{} 53 } 54 55 // KindProvider interface 56 func (m *MetricStorage) Kind() string { 57 return "PodMetrics" 58 } 59 60 // Lister interface 61 func (m *MetricStorage) NewList() runtime.Object { 62 return &metrics.PodMetricsList{} 63 } 64 65 // Lister interface 66 func (m *MetricStorage) List(ctx api.Context, options *api.ListOptions) (runtime.Object, error) { 67 labelSelector := labels.Everything() 68 if options != nil && options.LabelSelector != nil { 69 labelSelector = options.LabelSelector 70 } 71 namespace := api.NamespaceValue(ctx) 72 pods, err := m.podLister.Pods(namespace).List(labelSelector) 73 if err != nil { 74 errMsg := fmt.Errorf("Error while listing pods for selector %v: %v", labelSelector, err) 75 glog.Error(errMsg) 76 return &metrics.PodMetricsList{}, errMsg 77 } 78 79 res := metrics.PodMetricsList{} 80 for _, pod := range pods { 81 if podMetrics := m.getPodMetrics(pod); podMetrics != nil { 82 res.Items = append(res.Items, *podMetrics) 83 } else { 84 glog.Infof("No metrics for pod %s/%s", pod.Namespace, pod.Name) 85 } 86 } 87 return &res, nil 88 } 89 90 // Getter interface 91 func (m *MetricStorage) Get(ctx api.Context, name string) (runtime.Object, error) { 92 namespace := api.NamespaceValue(ctx) 93 94 pod, err := m.podLister.Pods(namespace).Get(name) 95 if err != nil { 96 errMsg := fmt.Errorf("Error while getting pod %v: %v", name, err) 97 glog.Error(errMsg) 98 return &metrics.PodMetrics{}, errMsg 99 } 100 if pod == nil { 101 return &metrics.PodMetrics{}, errors.NewNotFound(api.Resource("Pod"), fmt.Sprintf("%v/%v", namespace, name)) 102 } 103 104 podMetrics := m.getPodMetrics(pod) 105 if podMetrics == nil { 106 return &metrics.PodMetrics{}, errors.NewNotFound(m.groupResource, fmt.Sprintf("%v/%v", namespace, name)) 107 } 108 return podMetrics, nil 109 } 110 111 func (m *MetricStorage) getPodMetrics(pod *api.Pod) *metrics.PodMetrics { 112 batch := m.metricSink.GetLatestDataBatch() 113 if batch == nil { 114 return nil 115 } 116 117 res := &metrics.PodMetrics{ 118 ObjectMeta: api.ObjectMeta{ 119 Name: pod.Name, 120 Namespace: pod.Namespace, 121 CreationTimestamp: unversioned.NewTime(time.Now()), 122 }, 123 Timestamp: unversioned.NewTime(batch.Timestamp), 124 Window: unversioned.Duration{Duration: time.Minute}, 125 Containers: make([]metrics.ContainerMetrics, 0), 126 } 127 128 for _, c := range pod.Spec.Containers { 129 ms, found := batch.MetricSets[core.PodContainerKey(pod.Namespace, pod.Name, c.Name)] 130 if !found { 131 glog.Infof("No metrics for container %s in pod %s/%s", c.Name, pod.Namespace, pod.Name) 132 return nil 133 } 134 usage, err := util.ParseResourceList(ms) 135 if err != nil { 136 return nil 137 } 138 res.Containers = append(res.Containers, metrics.ContainerMetrics{Name: c.Name, Usage: usage}) 139 } 140 141 return res 142 }