Merge pull request #509 from rjnagal/summary
Add derived stats tracking to containers.
This commit is contained in:
commit
31769a89dd
@ -52,7 +52,9 @@ func GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info
|
|||||||
func GenerateRandomContainerSpec(numCores int) info.ContainerSpec {
|
func GenerateRandomContainerSpec(numCores int) info.ContainerSpec {
|
||||||
ret := info.ContainerSpec{
|
ret := info.ContainerSpec{
|
||||||
CreationTime: time.Now(),
|
CreationTime: time.Now(),
|
||||||
|
HasCpu: true,
|
||||||
Cpu: info.CpuSpec{},
|
Cpu: info.CpuSpec{},
|
||||||
|
HasMemory: true,
|
||||||
Memory: info.MemorySpec{},
|
Memory: info.MemorySpec{},
|
||||||
}
|
}
|
||||||
ret.Cpu.Limit = uint64(1000 + rand.Int63n(2000))
|
ret.Cpu.Limit = uint64(1000 + rand.Int63n(2000))
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/google/cadvisor/container"
|
"github.com/google/cadvisor/container"
|
||||||
"github.com/google/cadvisor/info"
|
"github.com/google/cadvisor/info"
|
||||||
"github.com/google/cadvisor/storage"
|
"github.com/google/cadvisor/storage"
|
||||||
|
"github.com/google/cadvisor/summary"
|
||||||
"github.com/google/cadvisor/utils/cpuload"
|
"github.com/google/cadvisor/utils/cpuload"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ type containerData struct {
|
|||||||
storageDriver storage.StorageDriver
|
storageDriver storage.StorageDriver
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
loadReader cpuload.CpuLoadReader
|
loadReader cpuload.CpuLoadReader
|
||||||
|
summaryReader *summary.StatsSummary
|
||||||
loadAvg float64 // smoothed load average seen so far.
|
loadAvg float64 // smoothed load average seen so far.
|
||||||
housekeepingInterval time.Duration
|
housekeepingInterval time.Duration
|
||||||
lastUpdatedTime time.Time
|
lastUpdatedTime time.Time
|
||||||
@ -121,6 +123,15 @@ func newContainerData(containerName string, driver storage.StorageDriver, handle
|
|||||||
}
|
}
|
||||||
cont.info.ContainerReference = ref
|
cont.info.ContainerReference = ref
|
||||||
|
|
||||||
|
err = cont.updateSpec()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cont.summaryReader, err = summary.New(cont.info.Spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create summary reader: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return cont, nil
|
return cont, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,6 +289,13 @@ func (c *containerData) updateStats() error {
|
|||||||
stats.Cpu.LoadAverage = int32(c.loadAvg * 1000)
|
stats.Cpu.LoadAverage = int32(c.loadAvg * 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if c.summaryReader != nil {
|
||||||
|
err := c.summaryReader.AddSample(*stats)
|
||||||
|
if err != nil {
|
||||||
|
// Ignore summary errors for now.
|
||||||
|
glog.V(2).Infof("failed to add summary stats for %q: %v", c.info.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
ref, err := c.handler.ContainerReference()
|
ref, err := c.handler.ContainerReference()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Ignore errors if the container is dead.
|
// Ignore errors if the container is dead.
|
||||||
|
@ -31,9 +31,13 @@ import (
|
|||||||
|
|
||||||
const containerName = "/container"
|
const containerName = "/container"
|
||||||
|
|
||||||
// Create a containerData instance for a test. Optionsl storage driver may be specified (one is made otherwise).
|
// Create a containerData instance for a test.
|
||||||
func newTestContainerData(t *testing.T) (*containerData, *container.MockContainerHandler, *stest.MockStorageDriver) {
|
func setupContainerData(t *testing.T, spec info.ContainerSpec) (*containerData, *container.MockContainerHandler, *stest.MockStorageDriver) {
|
||||||
mockHandler := container.NewMockContainerHandler(containerName)
|
mockHandler := container.NewMockContainerHandler(containerName)
|
||||||
|
mockHandler.On("GetSpec").Return(
|
||||||
|
spec,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
mockDriver := &stest.MockStorageDriver{}
|
mockDriver := &stest.MockStorageDriver{}
|
||||||
ret, err := newContainerData(containerName, mockDriver, mockHandler, nil, false)
|
ret, err := newContainerData(containerName, mockDriver, mockHandler, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -42,6 +46,13 @@ func newTestContainerData(t *testing.T) (*containerData, *container.MockContaine
|
|||||||
return ret, mockHandler, mockDriver
|
return ret, mockHandler, mockDriver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a containerData instance for a test and add a default GetSpec mock.
|
||||||
|
func newTestContainerData(t *testing.T) (*containerData, *container.MockContainerHandler, *stest.MockStorageDriver) {
|
||||||
|
spec := itest.GenerateRandomContainerSpec(4)
|
||||||
|
ret, mockHandler, mockDriver := setupContainerData(t, spec)
|
||||||
|
return ret, mockHandler, mockDriver
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdateSubcontainers(t *testing.T) {
|
func TestUpdateSubcontainers(t *testing.T) {
|
||||||
subcontainers := []info.ContainerReference{
|
subcontainers := []info.ContainerReference{
|
||||||
{Name: "/container/ee0103"},
|
{Name: "/container/ee0103"},
|
||||||
@ -146,11 +157,7 @@ func TestGetInfo(t *testing.T) {
|
|||||||
{Name: "/container/abcd"},
|
{Name: "/container/abcd"},
|
||||||
{Name: "/container/something"},
|
{Name: "/container/something"},
|
||||||
}
|
}
|
||||||
cd, mockHandler, _ := newTestContainerData(t)
|
cd, mockHandler, _ := setupContainerData(t, spec)
|
||||||
mockHandler.On("GetSpec").Return(
|
|
||||||
spec,
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
mockHandler.On("ListContainers", container.ListSelf).Return(
|
mockHandler.On("ListContainers", container.ListSelf).Return(
|
||||||
subcontainers,
|
subcontainers,
|
||||||
nil,
|
nil,
|
||||||
|
@ -50,6 +50,11 @@ func createManagerAndAddContainers(
|
|||||||
if ret, ok := mif.(*manager); ok {
|
if ret, ok := mif.(*manager); ok {
|
||||||
for _, name := range containers {
|
for _, name := range containers {
|
||||||
mockHandler := container.NewMockContainerHandler(name)
|
mockHandler := container.NewMockContainerHandler(name)
|
||||||
|
spec := itest.GenerateRandomContainerSpec(4)
|
||||||
|
mockHandler.On("GetSpec").Return(
|
||||||
|
spec,
|
||||||
|
nil,
|
||||||
|
).Once()
|
||||||
cont, err := newContainerData(name, driver, mockHandler, nil, false)
|
cont, err := newContainerData(name, driver, mockHandler, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -45,7 +45,7 @@ func (self uint64Slice) Get90Percentile() uint64 {
|
|||||||
idx, frac := math.Modf(n)
|
idx, frac := math.Modf(n)
|
||||||
index := int(idx)
|
index := int(idx)
|
||||||
percentile := float64(self[index-1])
|
percentile := float64(self[index-1])
|
||||||
if index > 1 || index < count {
|
if index > 1 && index < count {
|
||||||
percentile += frac * float64(self[index]-self[index-1])
|
percentile += frac * float64(self[index]-self[index-1])
|
||||||
}
|
}
|
||||||
return uint64(percentile)
|
return uint64(percentile)
|
||||||
|
Loading…
Reference in New Issue
Block a user