Add metrics caching

This commit is contained in:
anushree-n 2015-07-14 12:26:59 -07:00
parent d580ecfc53
commit e2e193c1fd
5 changed files with 44 additions and 28 deletions

View File

@ -22,12 +22,11 @@ import (
"github.com/google/cadvisor/info/v1" "github.com/google/cadvisor/info/v1"
) )
type collectorManager struct { type GenericCollectorManager struct {
collectors []*collectorData Collectors []*collectorData
NextCollectionTime time.Time
} }
var _ CollectorManager = &collectorManager{}
type collectorData struct { type collectorData struct {
collector Collector collector Collector
nextCollectionTime time.Time nextCollectionTime time.Time
@ -35,26 +34,27 @@ type collectorData struct {
// Returns a new CollectorManager that is thread-compatible. // Returns a new CollectorManager that is thread-compatible.
func NewCollectorManager() (CollectorManager, error) { func NewCollectorManager() (CollectorManager, error) {
return &collectorManager{ return &GenericCollectorManager{
collectors: []*collectorData{}, Collectors: []*collectorData{},
NextCollectionTime: time.Now(),
}, nil }, nil
} }
func (cm *collectorManager) RegisterCollector(collector Collector) error { func (cm *GenericCollectorManager) RegisterCollector(collector Collector) error {
cm.collectors = append(cm.collectors, &collectorData{ cm.Collectors = append(cm.Collectors, &collectorData{
collector: collector, collector: collector,
nextCollectionTime: time.Now(), nextCollectionTime: time.Now(),
}) })
return nil return nil
} }
func (cm *collectorManager) Collect() (time.Time, []v1.Metric, error) { func (cm *GenericCollectorManager) Collect() (time.Time, []v1.Metric, error) {
var errors []error var errors []error
// Collect from all collectors that are ready. // Collect from all collectors that are ready.
var next time.Time var next time.Time
var metrics []v1.Metric var metrics []v1.Metric
for _, c := range cm.collectors { for _, c := range cm.Collectors {
if c.nextCollectionTime.Before(time.Now()) { if c.nextCollectionTime.Before(time.Now()) {
nextCollection, newMetrics, err := c.collector.Collect() nextCollection, newMetrics, err := c.collector.Collect()
if err != nil { if err != nil {
@ -69,7 +69,7 @@ func (cm *collectorManager) Collect() (time.Time, []v1.Metric, error) {
next = c.nextCollectionTime next = c.nextCollectionTime
} }
} }
cm.NextCollectionTime = next
return next, metrics, compileErrors(errors) return next, metrics, compileErrors(errors)
} }

View File

@ -38,7 +38,7 @@ func (fc *fakeCollector) Name() string {
} }
func TestCollect(t *testing.T) { func TestCollect(t *testing.T) {
cm := &collectorManager{} cm := &GenericCollectorManager{}
firstTime := time.Now().Add(-time.Hour) firstTime := time.Now().Add(-time.Hour)
secondTime := time.Now().Add(time.Hour) secondTime := time.Now().Add(time.Hour)

View File

@ -340,19 +340,7 @@ func (c *containerData) housekeeping() {
} }
} }
// TODO(vmarmol): Export metrics. next := c.nextHousekeeping(lastHousekeeping)
// Run custom collectors.
nextCollectionTime, _, err := c.collectorManager.Collect()
if err != nil && c.allowErrorLogging() {
glog.Warningf("[%s] Collection failed: %v", c.info.Name, err)
}
// Next housekeeping is the first of the stats or the custom collector's housekeeping.
nextHousekeeping := c.nextHousekeeping(lastHousekeeping)
next := nextHousekeeping
if !nextCollectionTime.IsZero() && nextCollectionTime.Before(nextHousekeeping) {
next = nextCollectionTime
}
// Schedule the next housekeeping. Sleep until that time. // Schedule the next housekeeping. Sleep until that time.
if time.Now().Before(next) { if time.Now().Before(next) {
@ -432,6 +420,20 @@ func (c *containerData) updateStats() error {
glog.V(2).Infof("Failed to add summary stats for %q: %v", c.info.Name, err) glog.V(2).Infof("Failed to add summary stats for %q: %v", c.info.Name, err)
} }
} }
var customStatsErr error
if c.collectorManager != nil {
cm := c.collectorManager.(*collector.GenericCollectorManager)
if cm.NextCollectionTime.Before(time.Now()) {
customStats, err := c.updateCustomStats()
if customStats != nil {
stats.CustomMetrics = customStats
}
if err != nil {
customStatsErr = 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.
@ -444,7 +446,21 @@ func (c *containerData) updateStats() error {
if err != nil { if err != nil {
return err return err
} }
if statsErr != nil {
return statsErr return statsErr
}
return customStatsErr
}
func (c *containerData) updateCustomStats() ([]info.Metric, error) {
_, customStats, customStatsErr := c.collectorManager.Collect()
if customStatsErr != nil {
if !c.handler.Exists() {
return customStats, nil
}
customStatsErr = fmt.Errorf("%v, continuing to push custom stats", customStatsErr)
}
return customStats, customStatsErr
} }
func (c *containerData) updateSubcontainers() error { func (c *containerData) updateSubcontainers() error {

View File

@ -41,7 +41,7 @@ func setupContainerData(t *testing.T, spec info.ContainerSpec) (*containerData,
nil, nil,
) )
memoryCache := memory.New(60, nil) memoryCache := memory.New(60, nil)
ret, err := newContainerData(containerName, memoryCache, mockHandler, nil, false, &collector.FakeCollectorManager{}) ret, err := newContainerData(containerName, memoryCache, mockHandler, nil, false, &collector.GenericCollectorManager{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -53,7 +53,7 @@ func createManagerAndAddContainers(
spec, spec,
nil, nil,
).Once() ).Once()
cont, err := newContainerData(name, memoryCache, mockHandler, nil, false, &collector.FakeCollectorManager{}) cont, err := newContainerData(name, memoryCache, mockHandler, nil, false, &collector.GenericCollectorManager{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }