Merge pull request #277 from vmarmol/flat
Flatten ContainerStats struct
This commit is contained in:
commit
26921c3643
@ -95,7 +95,6 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont
|
|||||||
ret.Timestamp = time.Now()
|
ret.Timestamp = time.Now()
|
||||||
|
|
||||||
if s != nil {
|
if s != nil {
|
||||||
ret.Cpu = new(info.CpuStats)
|
|
||||||
ret.Cpu.Usage.User = s.CpuStats.CpuUsage.UsageInUsermode
|
ret.Cpu.Usage.User = s.CpuStats.CpuUsage.UsageInUsermode
|
||||||
ret.Cpu.Usage.System = s.CpuStats.CpuUsage.UsageInKernelmode
|
ret.Cpu.Usage.System = s.CpuStats.CpuUsage.UsageInKernelmode
|
||||||
n := len(s.CpuStats.CpuUsage.PercpuUsage)
|
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.IoMerged = DiskStatsCopy(s.BlkioStats.IoMergedRecursive)
|
||||||
ret.DiskIo.IoTime = DiskStatsCopy(s.BlkioStats.IoTimeRecursive)
|
ret.DiskIo.IoTime = DiskStatsCopy(s.BlkioStats.IoTimeRecursive)
|
||||||
|
|
||||||
ret.Memory = new(info.MemoryStats)
|
|
||||||
ret.Memory.Usage = s.MemoryStats.Usage
|
ret.Memory.Usage = s.MemoryStats.Usage
|
||||||
if v, ok := s.MemoryStats.Stats["pgfault"]; ok {
|
if v, ok := s.MemoryStats.Stats["pgfault"]; ok {
|
||||||
ret.Memory.ContainerData.Pgfault = v
|
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.
|
// TODO(vishh): Perform a deep copy or alias libcontainer network stats.
|
||||||
if libcontainerStats.NetworkStats != nil {
|
if libcontainerStats.NetworkStats != nil {
|
||||||
ret.Network = (*info.NetworkStats)(libcontainerStats.NetworkStats)
|
ret.Network = *(*info.NetworkStats)(libcontainerStats.NetworkStats)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -303,50 +303,15 @@ type FsStats struct {
|
|||||||
type ContainerStats struct {
|
type ContainerStats struct {
|
||||||
// The time of this stat point.
|
// The time of this stat point.
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
Cpu *CpuStats `json:"cpu,omitempty"`
|
Cpu CpuStats `json:"cpu,omitempty"`
|
||||||
DiskIo DiskIoStats `json:"diskio,omitempty"`
|
DiskIo DiskIoStats `json:"diskio,omitempty"`
|
||||||
Memory *MemoryStats `json:"memory,omitempty"`
|
Memory MemoryStats `json:"memory,omitempty"`
|
||||||
Network *NetworkStats `json:"network,omitempty"`
|
Network NetworkStats `json:"network,omitempty"`
|
||||||
|
|
||||||
// Filesystem statistics
|
// Filesystem statistics
|
||||||
Filesystem []FsStats `json:"filesystem,omitempty"`
|
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 {
|
func timeEq(t1, t2 time.Time, tolerance time.Duration) bool {
|
||||||
// t1 should not be later than t2
|
// t1 should not be later than t2
|
||||||
if t1.After(t2) {
|
if t1.After(t2) {
|
||||||
@ -386,12 +351,22 @@ func (a *ContainerStats) Eq(b *ContainerStats) bool {
|
|||||||
|
|
||||||
// Checks equality of the stats values.
|
// Checks equality of the stats values.
|
||||||
func (a *ContainerStats) StatsEq(b *ContainerStats) bool {
|
func (a *ContainerStats) StatsEq(b *ContainerStats) bool {
|
||||||
|
// TODO(vmarmol): Consider using this through reflection.
|
||||||
if !reflect.DeepEqual(a.Cpu, b.Cpu) {
|
if !reflect.DeepEqual(a.Cpu, b.Cpu) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(a.Memory, b.Memory) {
|
if !reflect.DeepEqual(a.Memory, b.Memory) {
|
||||||
return false
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
package info
|
package info
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -69,10 +68,7 @@ func TestStatsEndTime(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createStats(cpuUsage, memUsage uint64, timestamp time.Time) *ContainerStats {
|
func createStats(cpuUsage, memUsage uint64, timestamp time.Time) *ContainerStats {
|
||||||
stats := &ContainerStats{
|
stats := &ContainerStats{}
|
||||||
Cpu: &CpuStats{},
|
|
||||||
Memory: &MemoryStats{},
|
|
||||||
}
|
|
||||||
stats.Cpu.Usage.PerCpu = []uint64{cpuUsage}
|
stats.Cpu.Usage.PerCpu = []uint64{cpuUsage}
|
||||||
stats.Cpu.Usage.Total = cpuUsage
|
stats.Cpu.Usage.Total = cpuUsage
|
||||||
stats.Cpu.Usage.System = 0
|
stats.Cpu.Usage.System = 0
|
||||||
@ -81,21 +77,3 @@ func createStats(cpuUsage, memUsage uint64, timestamp time.Time) *ContainerStats
|
|||||||
stats.Timestamp = timestamp
|
stats.Timestamp = timestamp
|
||||||
return stats
|
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -31,8 +31,6 @@ func GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info
|
|||||||
}
|
}
|
||||||
for i := 0; i < numStats; i++ {
|
for i := 0; i < numStats; i++ {
|
||||||
stats := new(info.ContainerStats)
|
stats := new(info.ContainerStats)
|
||||||
stats.Cpu = new(info.CpuStats)
|
|
||||||
stats.Memory = new(info.MemoryStats)
|
|
||||||
stats.Timestamp = currentTime
|
stats.Timestamp = currentTime
|
||||||
currentTime = currentTime.Add(duration)
|
currentTime = currentTime.Add(duration)
|
||||||
|
|
||||||
|
@ -171,15 +171,8 @@ func (c *containerData) housekeeping() {
|
|||||||
} else if len(stats) < 2 {
|
} else if len(stats) < 2 {
|
||||||
// Ignore, not enough stats yet.
|
// Ignore, not enough stats yet.
|
||||||
} else {
|
} else {
|
||||||
usageCpuNs := uint64(0)
|
usageCpuNs := stats[1].Cpu.Usage.Total - stats[0].Cpu.Usage.Total
|
||||||
usageMemory := uint64(0)
|
usageMemory := stats[1].Memory.Usage
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
usageInCores := float64(usageCpuNs) / float64(stats[1].Timestamp.Sub(stats[0].Timestamp).Nanoseconds())
|
usageInCores := float64(usageCpuNs) / float64(stats[1].Timestamp.Sub(stats[0].Timestamp).Nanoseconds())
|
||||||
usageInHuman := units.HumanSize(int64(usageMemory))
|
usageInHuman := units.HumanSize(int64(usageMemory))
|
||||||
|
@ -223,13 +223,11 @@ func (self *bigqueryStorage) containerStatsToRows(
|
|||||||
// hierarchical major page fault
|
// hierarchical major page fault
|
||||||
row[colMemoryHierarchicalPgmajfault] = stats.Memory.HierarchicalData.Pgmajfault
|
row[colMemoryHierarchicalPgmajfault] = stats.Memory.HierarchicalData.Pgmajfault
|
||||||
|
|
||||||
// Optional: Network stats.
|
// Network stats.
|
||||||
if stats.Network != nil {
|
|
||||||
row[colRxBytes] = stats.Network.RxBytes
|
row[colRxBytes] = stats.Network.RxBytes
|
||||||
row[colRxErrors] = stats.Network.RxErrors
|
row[colRxErrors] = stats.Network.RxErrors
|
||||||
row[colTxBytes] = stats.Network.TxBytes
|
row[colTxBytes] = stats.Network.TxBytes
|
||||||
row[colTxErrors] = stats.Network.TxErrors
|
row[colTxErrors] = stats.Network.TxErrors
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(jnagal): Handle per-cpu stats.
|
// 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) {
|
func (self *bigqueryStorage) valuesToContainerStats(columns []string, values []interface{}) (*info.ContainerStats, error) {
|
||||||
stats := &info.ContainerStats{
|
stats := &info.ContainerStats{
|
||||||
Cpu: &info.CpuStats{},
|
|
||||||
Memory: &info.MemoryStats{},
|
|
||||||
Network: &info.NetworkStats{},
|
|
||||||
Filesystem: make([]info.FsStats, 0),
|
Filesystem: make([]info.FsStats, 0),
|
||||||
}
|
}
|
||||||
var err error
|
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 {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
rows := make([]map[string]interface{}, 0)
|
rows := make([]map[string]interface{}, 0)
|
||||||
|
@ -123,8 +123,7 @@ func (self *influxdbStorage) containerStatsToValues(
|
|||||||
columns = append(columns, colMemoryWorkingSet)
|
columns = append(columns, colMemoryWorkingSet)
|
||||||
values = append(values, stats.Memory.WorkingSet)
|
values = append(values, stats.Memory.WorkingSet)
|
||||||
|
|
||||||
// Optional: Network stats.
|
// Network stats.
|
||||||
if stats.Network != nil {
|
|
||||||
columns = append(columns, colRxBytes)
|
columns = append(columns, colRxBytes)
|
||||||
values = append(values, stats.Network.RxBytes)
|
values = append(values, stats.Network.RxBytes)
|
||||||
|
|
||||||
@ -136,7 +135,6 @@ func (self *influxdbStorage) containerStatsToValues(
|
|||||||
|
|
||||||
columns = append(columns, colTxErrors)
|
columns = append(columns, colTxErrors)
|
||||||
values = append(values, stats.Network.TxErrors)
|
values = append(values, stats.Network.TxErrors)
|
||||||
}
|
|
||||||
|
|
||||||
return columns, values
|
return columns, values
|
||||||
}
|
}
|
||||||
@ -176,9 +174,6 @@ func convertToUint64(v interface{}) (uint64, error) {
|
|||||||
|
|
||||||
func (self *influxdbStorage) valuesToContainerStats(columns []string, values []interface{}) (*info.ContainerStats, error) {
|
func (self *influxdbStorage) valuesToContainerStats(columns []string, values []interface{}) (*info.ContainerStats, error) {
|
||||||
stats := &info.ContainerStats{
|
stats := &info.ContainerStats{
|
||||||
Cpu: &info.CpuStats{},
|
|
||||||
Memory: &info.MemoryStats{},
|
|
||||||
Network: &info.NetworkStats{},
|
|
||||||
Filesystem: make([]info.FsStats, 0),
|
Filesystem: make([]info.FsStats, 0),
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
@ -261,7 +256,7 @@ func (self *influxdbStorage) defaultReadyToFlush() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *influxdbStorage) AddStats(ref info.ContainerReference, stats *info.ContainerStats) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
var seriesToFlush []*influxdb.Series
|
var seriesToFlush []*influxdb.Series
|
||||||
|
@ -41,8 +41,6 @@ func buildTrace(cpu, mem []uint64, duration time.Duration) []*info.ContainerStat
|
|||||||
for i, cpuUsage := range cpu {
|
for i, cpuUsage := range cpu {
|
||||||
cpuTotalUsage += cpuUsage
|
cpuTotalUsage += cpuUsage
|
||||||
stats := new(info.ContainerStats)
|
stats := new(info.ContainerStats)
|
||||||
stats.Cpu = new(info.CpuStats)
|
|
||||||
stats.Memory = new(info.MemoryStats)
|
|
||||||
stats.Timestamp = currentTime
|
stats.Timestamp = currentTime
|
||||||
currentTime = currentTime.Add(duration)
|
currentTime = currentTime.Add(duration)
|
||||||
|
|
||||||
@ -53,7 +51,6 @@ func buildTrace(cpu, mem []uint64, duration time.Duration) []*info.ContainerStat
|
|||||||
|
|
||||||
stats.Memory.Usage = mem[i]
|
stats.Memory.Usage = mem[i]
|
||||||
|
|
||||||
stats.Network = new(info.NetworkStats)
|
|
||||||
stats.Network.RxBytes = uint64(rand.Intn(10000))
|
stats.Network.RxBytes = uint64(rand.Intn(10000))
|
||||||
stats.Network.RxErrors = uint64(rand.Intn(1000))
|
stats.Network.RxErrors = uint64(rand.Intn(1000))
|
||||||
stats.Network.TxBytes = uint64(rand.Intn(100000))
|
stats.Network.TxBytes = uint64(rand.Intn(100000))
|
||||||
|
Loading…
Reference in New Issue
Block a user