2016-01-22 20:14:06 +00:00
|
|
|
/*
|
2016-06-03 00:25:58 +00:00
|
|
|
Copyright 2016 The Kubernetes Authors.
|
2016-01-22 20:14:06 +00:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package stats
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2016-01-14 19:19:26 +00:00
|
|
|
|
|
|
|
"github.com/golang/glog"
|
2016-04-06 21:57:54 +00:00
|
|
|
|
2017-08-18 22:08:44 +00:00
|
|
|
statsapi "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
|
2016-01-22 20:14:06 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type SummaryProvider interface {
|
2017-08-18 22:08:44 +00:00
|
|
|
Get() (*statsapi.Summary, error)
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
|
2017-08-18 22:08:44 +00:00
|
|
|
// summaryProviderImpl implements the SummaryProvider interface.
|
2016-01-22 20:14:06 +00:00
|
|
|
type summaryProviderImpl struct {
|
2017-08-18 22:08:44 +00:00
|
|
|
provider StatsProvider
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ SummaryProvider = &summaryProviderImpl{}
|
|
|
|
|
2017-08-18 22:08:44 +00:00
|
|
|
// NewSummaryProvider returns a SummaryProvider using the stats provided by the
|
|
|
|
// specified statsProvider.
|
|
|
|
func NewSummaryProvider(statsProvider StatsProvider) SummaryProvider {
|
|
|
|
return &summaryProviderImpl{statsProvider}
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
|
2017-08-18 22:08:44 +00:00
|
|
|
// Get provides a new Summary with the stats from Kubelet.
|
|
|
|
func (sp *summaryProviderImpl) Get() (*statsapi.Summary, error) {
|
|
|
|
// TODO(timstclair): Consider returning a best-effort response if any of
|
|
|
|
// the following errors occur.
|
2016-01-22 20:14:06 +00:00
|
|
|
node, err := sp.provider.GetNode()
|
|
|
|
if err != nil {
|
2017-08-18 22:08:44 +00:00
|
|
|
return nil, fmt.Errorf("failed to get node info: %v", err)
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
nodeConfig := sp.provider.GetNodeConfig()
|
2017-08-18 22:08:44 +00:00
|
|
|
rootStats, networkStats, err := sp.provider.GetCgroupStats("/")
|
2016-01-22 20:14:06 +00:00
|
|
|
if err != nil {
|
2017-08-18 22:08:44 +00:00
|
|
|
return nil, fmt.Errorf("failed to get root cgroup stats: %v", err)
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
2017-08-18 22:08:44 +00:00
|
|
|
rootFsStats, err := sp.provider.RootFsStats()
|
2016-01-22 20:14:06 +00:00
|
|
|
if err != nil {
|
2017-08-18 22:08:44 +00:00
|
|
|
return nil, fmt.Errorf("failed to get rootFs stats: %v", err)
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
2017-08-18 22:08:44 +00:00
|
|
|
imageFsStats, err := sp.provider.ImageFsStats()
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to get imageFs stats: %v", err)
|
2016-10-31 19:10:23 +00:00
|
|
|
}
|
2017-08-18 22:08:44 +00:00
|
|
|
podStats, err := sp.provider.ListPodStats()
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to list pod stats: %v", err)
|
2016-10-31 19:10:23 +00:00
|
|
|
}
|
|
|
|
|
2017-08-18 22:08:44 +00:00
|
|
|
nodeStats := statsapi.NodeStats{
|
|
|
|
NodeName: node.Name,
|
|
|
|
CPU: rootStats.CPU,
|
|
|
|
Memory: rootStats.Memory,
|
|
|
|
Network: networkStats,
|
2016-01-22 20:14:06 +00:00
|
|
|
StartTime: rootStats.StartTime,
|
2017-08-18 22:08:44 +00:00
|
|
|
Fs: rootFsStats,
|
|
|
|
Runtime: &statsapi.RuntimeStats{ImageFs: imageFsStats},
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
systemContainers := map[string]string{
|
2017-08-18 22:08:44 +00:00
|
|
|
statsapi.SystemContainerKubelet: nodeConfig.KubeletCgroupsName,
|
|
|
|
statsapi.SystemContainerRuntime: nodeConfig.RuntimeCgroupsName,
|
|
|
|
statsapi.SystemContainerMisc: nodeConfig.SystemCgroupsName,
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
for sys, name := range systemContainers {
|
2017-08-18 22:08:44 +00:00
|
|
|
s, _, err := sp.provider.GetCgroupStats(name)
|
|
|
|
if err != nil {
|
|
|
|
glog.Errorf("Failed to get system container stats for %q: %v", name, err)
|
|
|
|
continue
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
2017-08-18 22:08:44 +00:00
|
|
|
// System containers don't have a filesystem associated with them.
|
|
|
|
s.Logs, s.Rootfs = nil, nil
|
|
|
|
s.Name = sys
|
|
|
|
nodeStats.SystemContainers = append(nodeStats.SystemContainers, *s)
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
|
2017-08-18 22:08:44 +00:00
|
|
|
summary := statsapi.Summary{
|
2016-01-22 20:14:06 +00:00
|
|
|
Node: nodeStats,
|
2017-08-18 22:08:44 +00:00
|
|
|
Pods: podStats,
|
2016-01-22 20:14:06 +00:00
|
|
|
}
|
|
|
|
return &summary, nil
|
|
|
|
}
|