Merge 10c5dbf061
into 924821e4bf
This commit is contained in:
commit
2e84e3dd25
3 changed files with 69 additions and 9 deletions
14
lib/stats.go
14
lib/stats.go
|
@ -15,8 +15,8 @@ import (
|
||||||
type ContainerStats struct {
|
type ContainerStats struct {
|
||||||
Container string
|
Container string
|
||||||
CPU float64
|
CPU float64
|
||||||
cpuNano uint64
|
CPUNano uint64
|
||||||
systemNano uint64
|
SystemNano int64
|
||||||
MemUsage uint64
|
MemUsage uint64
|
||||||
MemLimit uint64
|
MemLimit uint64
|
||||||
MemPerc float64
|
MemPerc float64
|
||||||
|
@ -29,8 +29,8 @@ type ContainerStats struct {
|
||||||
|
|
||||||
// GetContainerStats gets the running stats for a given container
|
// GetContainerStats gets the running stats for a given container
|
||||||
func (c *ContainerServer) GetContainerStats(ctr *oci.Container, previousStats *ContainerStats) (*ContainerStats, error) {
|
func (c *ContainerServer) GetContainerStats(ctr *oci.Container, previousStats *ContainerStats) (*ContainerStats, error) {
|
||||||
previousCPU := previousStats.cpuNano
|
previousCPU := previousStats.CPUNano
|
||||||
previousSystem := previousStats.systemNano
|
previousSystem := previousStats.SystemNano
|
||||||
libcontainerStats, err := c.LibcontainerStats(ctr)
|
libcontainerStats, err := c.LibcontainerStats(ctr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -38,6 +38,8 @@ func (c *ContainerServer) GetContainerStats(ctr *oci.Container, previousStats *C
|
||||||
cgroupStats := libcontainerStats.CgroupStats
|
cgroupStats := libcontainerStats.CgroupStats
|
||||||
stats := new(ContainerStats)
|
stats := new(ContainerStats)
|
||||||
stats.Container = ctr.ID()
|
stats.Container = ctr.ID()
|
||||||
|
stats.CPUNano = cgroupStats.CpuStats.CpuUsage.TotalUsage
|
||||||
|
stats.SystemNano = time.Now().UnixNano()
|
||||||
stats.CPU = calculateCPUPercent(libcontainerStats, previousCPU, previousSystem)
|
stats.CPU = calculateCPUPercent(libcontainerStats, previousCPU, previousSystem)
|
||||||
stats.MemUsage = cgroupStats.MemoryStats.Usage.Usage
|
stats.MemUsage = cgroupStats.MemoryStats.Usage.Usage
|
||||||
stats.MemLimit = getMemLimit(cgroupStats.MemoryStats.Usage.Limit)
|
stats.MemLimit = getMemLimit(cgroupStats.MemoryStats.Usage.Limit)
|
||||||
|
@ -84,11 +86,11 @@ func getContainerNetIO(stats *libcontainer.Stats) (received uint64, transmitted
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateCPUPercent(stats *libcontainer.Stats, previousCPU, previousSystem uint64) float64 {
|
func calculateCPUPercent(stats *libcontainer.Stats, previousCPU uint64, previousSystem int64) float64 {
|
||||||
var (
|
var (
|
||||||
cpuPercent = 0.0
|
cpuPercent = 0.0
|
||||||
cpuDelta = float64(stats.CgroupStats.CpuStats.CpuUsage.TotalUsage - previousCPU)
|
cpuDelta = float64(stats.CgroupStats.CpuStats.CpuUsage.TotalUsage - previousCPU)
|
||||||
systemDelta = float64(uint64(time.Now().UnixNano()) - previousSystem)
|
systemDelta = float64(uint64(time.Now().UnixNano()) - uint64(previousSystem))
|
||||||
)
|
)
|
||||||
if systemDelta > 0.0 && cpuDelta > 0.0 {
|
if systemDelta > 0.0 && cpuDelta > 0.0 {
|
||||||
// gets a ratio of container cpu usage total, multiplies it by the number of cores (4 cores running
|
// gets a ratio of container cpu usage total, multiplies it by the number of cores (4 cores running
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/cri-o/lib"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||||
)
|
)
|
||||||
|
@ -16,5 +17,35 @@ func (s *Server) ContainerStats(ctx context.Context, req *pb.ContainerStatsReque
|
||||||
recordOperation(operation, time.Now())
|
recordOperation(operation, time.Now())
|
||||||
recordError(operation, err)
|
recordError(operation, err)
|
||||||
}()
|
}()
|
||||||
return nil, fmt.Errorf("not implemented")
|
|
||||||
|
container := s.GetContainer(req.ContainerId)
|
||||||
|
if container == nil {
|
||||||
|
return nil, fmt.Errorf("invalid container")
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UnixNano()
|
||||||
|
stats, err := s.GetContainerStats(container, &lib.ContainerStats{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.ContainerStatsResponse{
|
||||||
|
&pb.ContainerStats{
|
||||||
|
Attributes: &pb.ContainerAttributes{
|
||||||
|
Id: req.ContainerId,
|
||||||
|
Metadata: container.Metadata(),
|
||||||
|
Labels: container.Labels(),
|
||||||
|
Annotations: container.Annotations(),
|
||||||
|
},
|
||||||
|
Cpu: &pb.CpuUsage{
|
||||||
|
Timestamp: now,
|
||||||
|
UsageCoreNanoSeconds: &pb.UInt64Value{stats.CPUNano},
|
||||||
|
},
|
||||||
|
Memory: &pb.MemoryUsage{
|
||||||
|
Timestamp: now,
|
||||||
|
WorkingSetBytes: &pb.UInt64Value{stats.MemUsage},
|
||||||
|
},
|
||||||
|
WritableLayer: nil,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||||
)
|
)
|
||||||
|
@ -15,5 +15,32 @@ func (s *Server) ListContainerStats(ctx context.Context, req *pb.ListContainerSt
|
||||||
recordOperation(operation, time.Now())
|
recordOperation(operation, time.Now())
|
||||||
recordError(operation, err)
|
recordError(operation, err)
|
||||||
}()
|
}()
|
||||||
return nil, fmt.Errorf("not implemented")
|
|
||||||
|
// This is an inefficient method, since the container will be resolved twice,
|
||||||
|
// once by the container list code and once by the GetContainerStats call.
|
||||||
|
containers, err := s.ListContainers(ctx, &pb.ListContainersRequest{
|
||||||
|
&pb.ContainerFilter{
|
||||||
|
Id: req.Filter.Id,
|
||||||
|
PodSandboxId: req.Filter.PodSandboxId,
|
||||||
|
LabelSelector: req.Filter.LabelSelector,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var allStats []*pb.ContainerStats
|
||||||
|
|
||||||
|
for _, container := range containers.Containers {
|
||||||
|
stats, err := s.ContainerStats(ctx, &pb.ContainerStatsRequest{ContainerId: container.Id})
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warn("unable to get stats for container %s", container.Id)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
allStats = append(allStats, stats.Stats)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.ListContainerStatsResponse{
|
||||||
|
Stats: allStats,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue