changing info package to work with storage drivers.

This commit is contained in:
Nan Deng 2014-06-16 15:41:46 -07:00
parent 27f7bd7152
commit 6e98c92693
4 changed files with 30 additions and 20 deletions

View File

@ -118,9 +118,9 @@ func (self *percentilesContainerHandlerWrapper) StatsPercentiles() (*info.Contai
stats := d.(*info.ContainerStatsSample) stats := d.(*info.ContainerStatsSample)
samples = append(samples, stats) samples = append(samples, stats)
}) })
self.containerPercentiles.Samples = samples
// XXX(dengnan): probably add to StatsParameter? // XXX(dengnan): probably add to StatsParameter?
self.containerPercentiles.FillPercentiles( self.containerPercentiles.FillPercentiles(
samples,
[]int{50, 80, 90, 95, 99}, []int{50, 80, 90, 95, 99},
[]int{50, 80, 90, 95, 99}, []int{50, 80, 90, 95, 99},
) )

View File

@ -164,11 +164,13 @@ func TestSampleCpuUsage(t *testing.T) {
} }
} }
s, err := handler.StatsPercentiles() _, err := handler.StatsPercentiles()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
for _, sample := range s.Samples { hs := handler.(*percentilesContainerHandlerWrapper)
hs.sampler.Map(func(d interface{}) {
sample := d.(*info.ContainerStatsSample)
if sample.Duration != samplePeriod { if sample.Duration != samplePeriod {
t.Errorf("sample duration is %v, not %v", sample.Duration, samplePeriod) t.Errorf("sample duration is %v, not %v", sample.Duration, samplePeriod)
} }
@ -182,5 +184,5 @@ func TestSampleCpuUsage(t *testing.T) {
if !found { if !found {
t.Errorf("unable to find cpu usage %v", cpuUsage) t.Errorf("unable to find cpu usage %v", cpuUsage)
} }
} })
} }

View File

@ -69,6 +69,9 @@ type ContainerInfo struct {
// Historical statistics gathered from the container. // Historical statistics gathered from the container.
Stats []*ContainerStats `json:"stats,omitempty"` Stats []*ContainerStats `json:"stats,omitempty"`
// Randomly sampled container states.
Samples []*ContainerStatsSample `json:"samples,omitempty"`
StatsPercentiles *ContainerStatsPercentiles `json:"stats_summary,omitempty"` StatsPercentiles *ContainerStatsPercentiles `json:"stats_summary,omitempty"`
} }
@ -177,19 +180,15 @@ type ContainerStatsSample struct {
} `json:"memory"` } `json:"memory"`
} }
// This is not exported. type Percentile struct {
// Use FillPercentile to calculate percentiles
type percentile struct {
Percentage int `json:"percentage"` Percentage int `json:"percentage"`
Value uint64 `json:"value"` Value uint64 `json:"value"`
} }
type ContainerStatsPercentiles struct { type ContainerStatsPercentiles struct {
// TODO(dengnan): More things?
MaxMemoryUsage uint64 `json:"max_memory_usage,omitempty"` MaxMemoryUsage uint64 `json:"max_memory_usage,omitempty"`
Samples []*ContainerStatsSample `json:"samples,omitempty"` MemoryUsagePercentiles []Percentile `json:"memory_usage_percentiles,omitempty"`
MemoryUsagePercentiles []percentile `json:"memory_usage_percentiles,omitempty"` CpuUsagePercentiles []Percentile `json:"cpu_usage_percentiles,omitempty"`
CpuUsagePercentiles []percentile `json:"cpu_usage_percentiles,omitempty"`
} }
// Each sample needs two stats because the cpu usage in ContainerStats is // Each sample needs two stats because the cpu usage in ContainerStats is
@ -237,11 +236,11 @@ func (self uint64Slice) Swap(i, j int) {
self[i], self[j] = self[j], self[i] self[i], self[j] = self[j], self[i]
} }
func (self uint64Slice) Percentiles(requestedPercentiles ...int) []percentile { func (self uint64Slice) Percentiles(requestedPercentiles ...int) []Percentile {
if len(self) == 0 { if len(self) == 0 {
return nil return nil
} }
ret := make([]percentile, 0, len(requestedPercentiles)) ret := make([]Percentile, 0, len(requestedPercentiles))
sort.Sort(self) sort.Sort(self)
for _, p := range requestedPercentiles { for _, p := range requestedPercentiles {
idx := (len(self) * p / 100) - 1 idx := (len(self) * p / 100) - 1
@ -250,7 +249,7 @@ func (self uint64Slice) Percentiles(requestedPercentiles ...int) []percentile {
} }
ret = append( ret = append(
ret, ret,
percentile{ Percentile{
Percentage: p, Percentage: p,
Value: self[idx], Value: self[idx],
}, },
@ -259,14 +258,14 @@ func (self uint64Slice) Percentiles(requestedPercentiles ...int) []percentile {
return ret return ret
} }
func (self *ContainerStatsPercentiles) FillPercentiles(cpuPercentages, memoryPercentages []int) { func (self *ContainerStatsPercentiles) FillPercentiles(samples []*ContainerStatsSample, cpuPercentages, memoryPercentages []int) {
if len(self.Samples) == 0 { if len(samples) == 0 {
return return
} }
cpuUsages := make([]uint64, 0, len(self.Samples)) cpuUsages := make([]uint64, 0, len(samples))
memUsages := make([]uint64, 0, len(self.Samples)) memUsages := make([]uint64, 0, len(samples))
for _, sample := range self.Samples { for _, sample := range samples {
if sample == nil { if sample == nil {
continue continue
} }

View File

@ -18,4 +18,13 @@ import "github.com/google/cadvisor/info"
type StorageDriver interface { type StorageDriver interface {
AddStats(ref info.ContainerReference, stats *info.ContainerStats) error AddStats(ref info.ContainerReference, stats *info.ContainerStats) error
// Read most recent stats. numStats indicates max number of stats
// returned. The returned stats must be consecutive observed stats. If
// numStats < 0, then return all stats stored in the storage.
RecentStats(numStats int) ([]*info.ContainerStats, error)
Percentiles(cpuUsagePercentiles []int, memUsagePercentiles []int) (*info.ContainerStatsPercentiles, error)
Samples(numSamples int) ([]*info.ContainerStatsSample, error)
} }