add /containerStats

This commit is contained in:
Nan Deng 2014-06-19 01:26:23 +00:00
parent 2402e939c2
commit 037cfd257f
3 changed files with 87 additions and 1 deletions

View File

@ -66,6 +66,20 @@ type Container struct {
VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`
}
// Percentile represents a pair which contains a percentage from 0 to 100 and
// its corresponding value.
type Percentile struct {
Percentage int `json:"percentage,omitempty"`
Value uint64 `json:"value,omitempty"`
}
// ContainerStats represents statistical information of a container
type ContainerStats struct {
CpuUsagePercentiles []Percentile `json:"cpu_usage_percentiles,omitempty"`
MemoryUsagePercentiles []Percentile `json:"memory_usage_percentiles,omitempty"`
MaxMemoryUsage uint64 `json:"max_memory_usage,omitempty"`
}
// Event is the representation of an event logged to etcd backends
type Event struct {
Event string `json:"event,omitempty"`

View File

@ -34,8 +34,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/third_party/src/github.com/fsouza/go-dockerclient"
"github.com/coreos/go-etcd/etcd"
"github.com/fsouza/go-dockerclient"
"github.com/google/cadvisor/info"
"gopkg.in/v1/yaml"
)
@ -650,3 +650,46 @@ func (kl *Kubelet) GetContainerInfo(name string) (string, error) {
data, err := json.Marshal(info)
return string(data), err
}
func (kl *Kubelet) GetContainerStats(name string) (*api.ContainerStats, error) {
if kl.CadvisorClient == nil {
return nil, nil
}
id, found, err := kl.GetContainerID(name)
if err != nil {
return nil, err
}
if !found {
return nil, nil
}
path := fmt.Sprintf("/docker/%v", id)
info, err := kl.CadvisorClient.ContainerInfo(path)
if err != nil {
return nil, err
}
if info.StatsPercentiles == nil {
return nil, nil
}
ret := new(api.ContainerStats)
ret.MaxMemoryUsage = info.StatsPercentiles.MaxMemoryUsage
if len(info.StatsPercentiles.CpuUsagePercentiles) > 0 {
percentiles := make([]api.Percentile, len(info.StatsPercentiles.CpuUsagePercentiles))
for i, p := range info.StatsPercentiles.CpuUsagePercentiles {
percentiles[i].Percentage = p.Percentage
percentiles[i].Value = p.Value
}
ret.CpuUsagePercentiles = percentiles
}
if len(info.StatsPercentiles.MemoryUsagePercentiles) > 0 {
percentiles := make([]api.Percentile, len(info.StatsPercentiles.MemoryUsagePercentiles))
for i, p := range info.StatsPercentiles.MemoryUsagePercentiles {
percentiles[i].Percentage = p.Percentage
percentiles[i].Value = p.Value
}
ret.MemoryUsagePercentiles = percentiles
}
return ret, nil
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package kubelet
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
@ -35,6 +36,7 @@ type KubeletServer struct {
// For testablitiy.
type kubeletInterface interface {
GetContainerID(name string) (string, bool, error)
GetContainerStats(name string) (*api.ContainerStats, error)
GetContainerInfo(name string) (string, error)
}
@ -64,6 +66,33 @@ func (s *KubeletServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
s.UpdateChannel <- manifest
case u.Path == "/containerStats":
container := u.Query().Get("container")
if len(container) == 0 {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "Missing container query arg.")
return
}
stats, err := s.Kubelet.GetContainerStats(container)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "Internal Error: %#v", err)
return
}
if stats == nil {
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "{}")
return
}
w.Header().Add("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
encoder := json.NewEncoder(w)
err = encoder.Encode(stats)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "Internal Error: %#v", err)
return
}
case u.Path == "/containerInfo":
container := u.Query().Get("container")
if len(container) == 0 {