Merge pull request #277 from vmarmol/flat

Flatten ContainerStats struct
This commit is contained in:
Vish Kannan 2014-11-05 11:26:10 -08:00
commit 26921c3643
8 changed files with 36 additions and 107 deletions

View File

@ -95,7 +95,6 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont
ret.Timestamp = time.Now()
if s != nil {
ret.Cpu = new(info.CpuStats)
ret.Cpu.Usage.User = s.CpuStats.CpuUsage.UsageInUsermode
ret.Cpu.Usage.System = s.CpuStats.CpuUsage.UsageInKernelmode
n := len(s.CpuStats.CpuUsage.PercpuUsage)
@ -116,7 +115,6 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont
ret.DiskIo.IoMerged = DiskStatsCopy(s.BlkioStats.IoMergedRecursive)
ret.DiskIo.IoTime = DiskStatsCopy(s.BlkioStats.IoTimeRecursive)
ret.Memory = new(info.MemoryStats)
ret.Memory.Usage = s.MemoryStats.Usage
if v, ok := s.MemoryStats.Stats["pgfault"]; ok {
ret.Memory.ContainerData.Pgfault = v
@ -135,7 +133,7 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont
}
// TODO(vishh): Perform a deep copy or alias libcontainer network stats.
if libcontainerStats.NetworkStats != nil {
ret.Network = (*info.NetworkStats)(libcontainerStats.NetworkStats)
ret.Network = *(*info.NetworkStats)(libcontainerStats.NetworkStats)
}
return ret

View File

@ -303,50 +303,15 @@ type FsStats struct {
type ContainerStats struct {
// The time of this stat point.
Timestamp time.Time `json:"timestamp"`
Cpu *CpuStats `json:"cpu,omitempty"`
Cpu CpuStats `json:"cpu,omitempty"`
DiskIo DiskIoStats `json:"diskio,omitempty"`
Memory *MemoryStats `json:"memory,omitempty"`
Network *NetworkStats `json:"network,omitempty"`
Memory MemoryStats `json:"memory,omitempty"`
Network NetworkStats `json:"network,omitempty"`
// Filesystem statistics
Filesystem []FsStats `json:"filesystem,omitempty"`
}
// Makes a deep copy of the ContainerStats and returns a pointer to the new
// copy. Copy() will allocate a new ContainerStats object if dst is nil.
func (self *ContainerStats) Copy(dst *ContainerStats) *ContainerStats {
if dst == nil {
dst = new(ContainerStats)
}
dst.Timestamp = self.Timestamp
if self.Cpu != nil {
if dst.Cpu == nil {
dst.Cpu = new(CpuStats)
}
// To make a deep copy of a slice, we need to copy every value
// in the slice. To make less memory allocation, we would like
// to reuse the slice in dst if possible.
percpu := dst.Cpu.Usage.PerCpu
if len(percpu) != len(self.Cpu.Usage.PerCpu) {
percpu = make([]uint64, len(self.Cpu.Usage.PerCpu))
}
dst.Cpu.Usage = self.Cpu.Usage
dst.Cpu.Load = self.Cpu.Load
copy(percpu, self.Cpu.Usage.PerCpu)
dst.Cpu.Usage.PerCpu = percpu
} else {
dst.Cpu = nil
}
if self.Memory != nil {
if dst.Memory == nil {
dst.Memory = new(MemoryStats)
}
*dst.Memory = *self.Memory
} else {
dst.Memory = nil
}
return dst
}
func timeEq(t1, t2 time.Time, tolerance time.Duration) bool {
// t1 should not be later than t2
if t1.After(t2) {
@ -386,12 +351,22 @@ func (a *ContainerStats) Eq(b *ContainerStats) bool {
// Checks equality of the stats values.
func (a *ContainerStats) StatsEq(b *ContainerStats) bool {
// TODO(vmarmol): Consider using this through reflection.
if !reflect.DeepEqual(a.Cpu, b.Cpu) {
return false
}
if !reflect.DeepEqual(a.Memory, b.Memory) {
return false
}
if !reflect.DeepEqual(a.DiskIo, b.DiskIo) {
return false
}
if !reflect.DeepEqual(a.Network, b.Network) {
return false
}
if !reflect.DeepEqual(a.Filesystem, b.Filesystem) {
return false
}
return true
}

View File

@ -15,7 +15,6 @@
package info
import (
"reflect"
"testing"
"time"
)
@ -69,10 +68,7 @@ func TestStatsEndTime(t *testing.T) {
}
func createStats(cpuUsage, memUsage uint64, timestamp time.Time) *ContainerStats {
stats := &ContainerStats{
Cpu: &CpuStats{},
Memory: &MemoryStats{},
}
stats := &ContainerStats{}
stats.Cpu.Usage.PerCpu = []uint64{cpuUsage}
stats.Cpu.Usage.Total = cpuUsage
stats.Cpu.Usage.System = 0
@ -81,21 +77,3 @@ func createStats(cpuUsage, memUsage uint64, timestamp time.Time) *ContainerStats
stats.Timestamp = timestamp
return stats
}
func TestContainerStatsCopy(t *testing.T) {
stats := createStats(100, 101, time.Now())
shadowStats := stats.Copy(nil)
if !reflect.DeepEqual(stats, shadowStats) {
t.Errorf("Copy() returned different object")
}
stats.Cpu.Usage.PerCpu[0] = shadowStats.Cpu.Usage.PerCpu[0] + 1
stats.Cpu.Load = shadowStats.Cpu.Load + 1
stats.Memory.Usage = shadowStats.Memory.Usage + 1
if reflect.DeepEqual(stats, shadowStats) {
t.Errorf("Copy() did not deeply copy the object")
}
stats = shadowStats.Copy(stats)
if !reflect.DeepEqual(stats, shadowStats) {
t.Errorf("Copy() returned different object")
}
}

View File

@ -31,8 +31,6 @@ func GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info
}
for i := 0; i < numStats; i++ {
stats := new(info.ContainerStats)
stats.Cpu = new(info.CpuStats)
stats.Memory = new(info.MemoryStats)
stats.Timestamp = currentTime
currentTime = currentTime.Add(duration)

View File

@ -171,15 +171,8 @@ func (c *containerData) housekeeping() {
} else if len(stats) < 2 {
// Ignore, not enough stats yet.
} else {
usageCpuNs := uint64(0)
usageMemory := uint64(0)
if stats[0].Cpu != nil && stats[1].Cpu != nil {
usageCpuNs = stats[1].Cpu.Usage.Total - stats[0].Cpu.Usage.Total
}
if stats[1].Memory != nil {
usageMemory = stats[1].Memory.Usage
}
usageCpuNs := stats[1].Cpu.Usage.Total - stats[0].Cpu.Usage.Total
usageMemory := stats[1].Memory.Usage
usageInCores := float64(usageCpuNs) / float64(stats[1].Timestamp.Sub(stats[0].Timestamp).Nanoseconds())
usageInHuman := units.HumanSize(int64(usageMemory))

View File

@ -223,13 +223,11 @@ func (self *bigqueryStorage) containerStatsToRows(
// hierarchical major page fault
row[colMemoryHierarchicalPgmajfault] = stats.Memory.HierarchicalData.Pgmajfault
// Optional: Network stats.
if stats.Network != nil {
// Network stats.
row[colRxBytes] = stats.Network.RxBytes
row[colRxErrors] = stats.Network.RxErrors
row[colTxBytes] = stats.Network.TxBytes
row[colTxErrors] = stats.Network.TxErrors
}
// TODO(jnagal): Handle per-cpu stats.
@ -288,9 +286,6 @@ func convertToUint64(v interface{}) (uint64, error) {
func (self *bigqueryStorage) valuesToContainerStats(columns []string, values []interface{}) (*info.ContainerStats, error) {
stats := &info.ContainerStats{
Cpu: &info.CpuStats{},
Memory: &info.MemoryStats{},
Network: &info.NetworkStats{},
Filesystem: make([]info.FsStats, 0),
}
var err error
@ -383,7 +378,7 @@ func (self *bigqueryStorage) valuesToContainerStats(columns []string, values []i
}
func (self *bigqueryStorage) AddStats(ref info.ContainerReference, stats *info.ContainerStats) error {
if stats == nil || stats.Cpu == nil || stats.Memory == nil {
if stats == nil {
return nil
}
rows := make([]map[string]interface{}, 0)

View File

@ -123,8 +123,7 @@ func (self *influxdbStorage) containerStatsToValues(
columns = append(columns, colMemoryWorkingSet)
values = append(values, stats.Memory.WorkingSet)
// Optional: Network stats.
if stats.Network != nil {
// Network stats.
columns = append(columns, colRxBytes)
values = append(values, stats.Network.RxBytes)
@ -136,7 +135,6 @@ func (self *influxdbStorage) containerStatsToValues(
columns = append(columns, colTxErrors)
values = append(values, stats.Network.TxErrors)
}
return columns, values
}
@ -176,9 +174,6 @@ func convertToUint64(v interface{}) (uint64, error) {
func (self *influxdbStorage) valuesToContainerStats(columns []string, values []interface{}) (*info.ContainerStats, error) {
stats := &info.ContainerStats{
Cpu: &info.CpuStats{},
Memory: &info.MemoryStats{},
Network: &info.NetworkStats{},
Filesystem: make([]info.FsStats, 0),
}
var err error
@ -261,7 +256,7 @@ func (self *influxdbStorage) defaultReadyToFlush() bool {
}
func (self *influxdbStorage) AddStats(ref info.ContainerReference, stats *info.ContainerStats) error {
if stats == nil || stats.Cpu == nil || stats.Memory == nil {
if stats == nil {
return nil
}
var seriesToFlush []*influxdb.Series

View File

@ -41,8 +41,6 @@ func buildTrace(cpu, mem []uint64, duration time.Duration) []*info.ContainerStat
for i, cpuUsage := range cpu {
cpuTotalUsage += cpuUsage
stats := new(info.ContainerStats)
stats.Cpu = new(info.CpuStats)
stats.Memory = new(info.MemoryStats)
stats.Timestamp = currentTime
currentTime = currentTime.Add(duration)
@ -53,7 +51,6 @@ func buildTrace(cpu, mem []uint64, duration time.Duration) []*info.ContainerStat
stats.Memory.Usage = mem[i]
stats.Network = new(info.NetworkStats)
stats.Network.RxBytes = uint64(rand.Intn(10000))
stats.Network.RxErrors = uint64(rand.Intn(1000))
stats.Network.TxBytes = uint64(rand.Intn(100000))