diff --git a/storage/memory/memory.go b/storage/memory/memory.go index d30a3df62c..a8577bdbf3 100644 --- a/storage/memory/memory.go +++ b/storage/memory/memory.go @@ -151,6 +151,7 @@ type InMemoryStorage struct { containerStorageMap map[string]*containerStorage maxNumSamples int maxNumStats int + backend storage.StorageDriver } func (self *InMemoryStorage) AddStats(ref info.ContainerReference, stats *info.ContainerStats) error { @@ -165,6 +166,13 @@ func (self *InMemoryStorage) AddStats(ref info.ContainerReference, stats *info.C self.containerStorageMap[ref.Name] = cstore } }() + + if self.backend != nil { + // TODO(monnand): To deal with long delay write operations, we + // may want to start a pool of goroutines to do write + // operations. + self.backend.AddStats(ref, stats) + } return cstore.AddStats(stats) } @@ -231,11 +239,16 @@ func (self *InMemoryStorage) Close() error { return nil } -func New(maxNumSamples, maxNumStats int) storage.StorageDriver { +func New( + maxNumSamples, + maxNumStats int, + backend storage.StorageDriver, +) *InMemoryStorage { ret := &InMemoryStorage{ containerStorageMap: make(map[string]*containerStorage, 32), maxNumSamples: maxNumSamples, maxNumStats: maxNumStats, + backend: backend, } return ret } diff --git a/storage/memory/memory_test.go b/storage/memory/memory_test.go index e29759abac..52f0941704 100644 --- a/storage/memory/memory_test.go +++ b/storage/memory/memory_test.go @@ -23,39 +23,19 @@ import ( ) type memoryTestStorageDriver struct { - base storage.StorageDriver + storage.StorageDriver } func (self *memoryTestStorageDriver) StatsEq(a, b *info.ContainerStats) bool { return test.DefaultStatsEq(a, b) } -func (self *memoryTestStorageDriver) AddStats(ref info.ContainerReference, stats *info.ContainerStats) error { - return self.base.AddStats(ref, stats) -} - -func (self *memoryTestStorageDriver) RecentStats(containerName string, numStats int) ([]*info.ContainerStats, error) { - return self.base.RecentStats(containerName, numStats) -} - -func (self *memoryTestStorageDriver) Percentiles(containerName string, cpuUsagePercentiles []int, memUsagePercentiles []int) (*info.ContainerStatsPercentiles, error) { - return self.base.Percentiles(containerName, cpuUsagePercentiles, memUsagePercentiles) -} - -func (self *memoryTestStorageDriver) Samples(containerName string, numSamples int) ([]*info.ContainerStatsSample, error) { - return self.base.Samples(containerName, numSamples) -} - -func (self *memoryTestStorageDriver) Close() error { - return self.base.Close() -} - func runStorageTest(f func(test.TestStorageDriver, *testing.T), t *testing.T) { maxSize := 200 for N := 10; N < maxSize; N += 10 { testDriver := &memoryTestStorageDriver{} - testDriver.base = New(N, N) + testDriver.StorageDriver = New(N, N, nil) f(testDriver, t) } } @@ -79,7 +59,7 @@ func TestPercentilesWithoutSample(t *testing.T) { func TestPercentiles(t *testing.T) { N := 100 testDriver := &memoryTestStorageDriver{} - testDriver.base = New(N, N) + testDriver.StorageDriver = New(N, N, nil) test.StorageDriverTestPercentiles(testDriver, t) } diff --git a/storagedriver.go b/storagedriver.go index ab6e09e203..9b1fbd83e9 100644 --- a/storagedriver.go +++ b/storagedriver.go @@ -24,7 +24,6 @@ import ( "github.com/google/cadvisor/manager" "github.com/google/cadvisor/storage" "github.com/google/cadvisor/storage/bigquery" - "github.com/google/cadvisor/storage/cache" "github.com/google/cadvisor/storage/influxdb" "github.com/google/cadvisor/storage/memory" ) @@ -39,8 +38,9 @@ var argDbBufferDuration = flag.Duration("storage_driver_buffer_duration", 60*tim const statsRequestedByUI = 60 -func NewStorageDriver(driverName string) (storage.StorageDriver, error) { - var storageDriver storage.StorageDriver +func NewStorageDriver(driverName string) (*memory.InMemoryStorage, error) { + var storageDriver *memory.InMemoryStorage + var backendStorage storage.StorageDriver var err error // TODO(vmarmol): We shouldn't need the housekeeping interval here and it shouldn't be public. samplesToCache := int(*argDbBufferDuration / *manager.HousekeepingInterval) @@ -49,12 +49,6 @@ func NewStorageDriver(driverName string) (storage.StorageDriver, error) { samplesToCache = statsRequestedByUI } switch driverName { - case "": - // empty string by default is the in memory store - fallthrough - case "memory": - storageDriver = memory.New(*argSampleSize, int(*argDbBufferDuration)) - return storageDriver, nil case "influxdb": var hostname string hostname, err = os.Hostname() @@ -62,7 +56,7 @@ func NewStorageDriver(driverName string) (storage.StorageDriver, error) { return nil, err } - storageDriver, err = influxdb.New( + backendStorage, err = influxdb.New( hostname, "stats", *argDbName, @@ -74,22 +68,18 @@ func NewStorageDriver(driverName string) (storage.StorageDriver, error) { // TODO(monnand): One hour? Or user-defined? 1*time.Hour, ) - glog.V(2).Infof("Caching %d recent stats in memory\n", samplesToCache) - storageDriver = cache.MemoryCache(samplesToCache, samplesToCache, storageDriver) case "bigquery": var hostname string hostname, err = os.Hostname() if err != nil { return nil, err } - storageDriver, err = bigquery.New( + backendStorage, err = bigquery.New( hostname, "cadvisor", *argDbName, 1*time.Hour, ) - glog.V(2).Infof("Caching %d recent stats in memory\n", samplesToCache) - storageDriver = cache.MemoryCache(samplesToCache, samplesToCache, storageDriver) default: err = fmt.Errorf("Unknown database driver: %v", *argDbDriver) @@ -97,5 +87,7 @@ func NewStorageDriver(driverName string) (storage.StorageDriver, error) { if err != nil { return nil, err } + glog.V(2).Infof("Caching %d recent stats in memory; using %v storage driver\n", samplesToCache, driverName) + storageDriver = memory.New(samplesToCache, samplesToCache, backendStorage) return storageDriver, nil }