diff --git a/manager/container.go b/manager/container.go index ac7e03a2..90d72647 100644 --- a/manager/container.go +++ b/manager/container.go @@ -25,6 +25,7 @@ import ( "github.com/google/cadvisor/container" "github.com/google/cadvisor/info" + "github.com/google/cadvisor/storage" ) var historyDuration = flag.Int("history_duration", 60, "number of seconds of container history to keep") @@ -43,10 +44,10 @@ type containerInfo struct { } type containerData struct { - handler container.ContainerHandler - info containerInfo - statsChan chan<- *ContainerStats - lock sync.Mutex + handler container.ContainerHandler + info containerInfo + storageDriver storage.StorageDriver + lock sync.Mutex // Tells the container to stop. stop chan bool @@ -85,7 +86,7 @@ func (c *containerData) GetInfo() (*containerInfo, error) { return &ret, nil } -func NewContainerData(containerName string, statsChan chan<- *ContainerStats) (*containerData, error) { +func NewContainerData(containerName string, driver storage.StorageDriver) (*containerData, error) { cont := &containerData{} handler, err := container.NewContainerHandler(containerName) if err != nil { @@ -99,7 +100,7 @@ func NewContainerData(containerName string, statsChan chan<- *ContainerStats) (* cont.info.Name = ref.Name cont.info.Aliases = ref.Aliases cont.info.Stats = list.New() - cont.statsChan = statsChan + cont.storageDriver = driver cont.stop = make(chan bool, 1) return cont, nil @@ -153,13 +154,14 @@ func (c *containerData) updateStats() error { if stats == nil { return nil } - if c.statsChan != nil { + if c.storageDriver != nil { ref, err := c.handler.ContainerReference() - if err == nil { - c.statsChan <- &ContainerStats{ - ContainerReference: ref, - Stats: stats, - } + if err != nil { + return err + } + err = c.storageDriver.WriteStats(ref, stats) + if err != nil { + return err } } summary, err := c.handler.StatsSummary() diff --git a/manager/manager.go b/manager/manager.go index c86bd830..de3ad29e 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -39,7 +39,7 @@ type Manager interface { GetVersionInfo() (*info.VersionInfo, error) } -func New(statsWriter storage.ContainerStatsWriter) (Manager, error) { +func New(driver storage.StorageDriver) (Manager, error) { newManager := &manager{} newManager.containers = make(map[string]*containerData) @@ -56,15 +56,7 @@ func New(statsWriter storage.ContainerStatsWriter) (Manager, error) { } newManager.versionInfo = *versionInfo log.Printf("Version: %+v", newManager.versionInfo) - if statsWriter != nil { - // XXX(monnand): about numWorkers and queueLength, should we make it - // configurable? - ch, err := StartContainerStatsWriters(16, 64, statsWriter) - if err != nil { - return nil, err - } - newManager.statsChan = ch - } + newManager.storageDriver = driver return newManager, nil } @@ -72,7 +64,7 @@ func New(statsWriter storage.ContainerStatsWriter) (Manager, error) { type manager struct { containers map[string]*containerData containersLock sync.RWMutex - statsChan chan<- *ContainerStats + storageDriver storage.StorageDriver machineInfo info.MachineInfo versionInfo info.VersionInfo } @@ -171,7 +163,7 @@ func (m *manager) GetVersionInfo() (*info.VersionInfo, error) { // Create a container. This expects to only be called from the global manager thread. func (m *manager) createContainer(containerName string) (*containerData, error) { - cont, err := NewContainerData(containerName, m.statsChan) + cont, err := NewContainerData(containerName, m.storageDriver) if err != nil { return nil, err } diff --git a/manager/statsproc.go b/manager/statsproc.go index 6011f3ec..b9fdb366 100644 --- a/manager/statsproc.go +++ b/manager/statsproc.go @@ -36,7 +36,7 @@ type ContainerStats struct { func StartContainerStatsWriters( numWorkers int, queueLength int, - statsWriter storage.ContainerStatsWriter, + statsWriter storage.StorageDriver, ) (chan<- *ContainerStats, error) { if statsWriter == nil { return nil, fmt.Errorf("invalid stats writer") @@ -53,7 +53,7 @@ func StartContainerStatsWriters( return ch, nil } -func writeContainerStats(statsWriter storage.ContainerStatsWriter, ch <-chan *ContainerStats) { +func writeContainerStats(statsWriter storage.StorageDriver, ch <-chan *ContainerStats) { for stats := range ch { err := statsWriter.Write(stats.ContainerReference, stats.Stats) if err != nil { diff --git a/storage/storage.go b/storage/storage.go index 253881ae..101a7b87 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -21,8 +21,8 @@ import ( "github.com/google/cadvisor/info" ) -type ContainerStatsWriter interface { - Write(ref info.ContainerReference, stats *info.ContainerStats) error +type StorageDriver interface { + WriteStats(ref info.ContainerReference, stats *info.ContainerStats) error } // Database config which should contain all information used to connect to @@ -37,28 +37,28 @@ type Config struct { Params map[string]string `json:"parameters,omitempty"` } -type ContainerStatsWriterFactory interface { +type StorageFactory interface { String() string - New(config *Config) (ContainerStatsWriter, error) + New(config *Config) (StorageDriver, error) } type containerStatsWriterFactoryManager struct { lock sync.RWMutex - factories map[string]ContainerStatsWriterFactory + factories map[string]StorageFactory } -func (self *containerStatsWriterFactoryManager) Register(factory ContainerStatsWriterFactory) { +func (self *containerStatsWriterFactoryManager) Register(factory StorageFactory) { self.lock.Lock() defer self.lock.Unlock() if self.factories == nil { - self.factories = make(map[string]ContainerStatsWriterFactory, 8) + self.factories = make(map[string]StorageFactory, 8) } self.factories[factory.String()] = factory } -func (self *containerStatsWriterFactoryManager) New(config *Config) (ContainerStatsWriter, error) { +func (self *containerStatsWriterFactoryManager) New(config *Config) (StorageDriver, error) { self.lock.RLock() defer self.lock.RUnlock() @@ -70,10 +70,10 @@ func (self *containerStatsWriterFactoryManager) New(config *Config) (ContainerSt var globalContainerStatsWriterFactoryManager containerStatsWriterFactoryManager -func RegisterContainerStatsWriterFactory(factory ContainerStatsWriterFactory) { +func RegisterStorage(factory StorageFactory) { globalContainerStatsWriterFactoryManager.Register(factory) } -func NewContainerStatsWriter(config *Config) (ContainerStatsWriter, error) { +func NewStorage(config *Config) (StorageDriver, error) { return globalContainerStatsWriterFactoryManager.New(config) } diff --git a/storage/storage_test.go b/storage/storage_test.go index 2c9ffa0b..d058fbe9 100644 --- a/storage/storage_test.go +++ b/storage/storage_test.go @@ -8,12 +8,12 @@ import ( "github.com/stretchr/testify/mock" ) -type mockContainerStatsWriter struct { +type mockStorageDriver struct { storageName string mock.Mock } -func (self *mockContainerStatsWriter) Write( +func (self *mockStorageDriver) WriteStats( ref info.ContainerReference, stats *info.ContainerStats, ) error { @@ -21,18 +21,18 @@ func (self *mockContainerStatsWriter) Write( return args.Error(0) } -type mockContainerStatsWriterFactory struct { +type mockStorageFactory struct { name string } -func (self *mockContainerStatsWriterFactory) String() string { +func (self *mockStorageFactory) String() string { return self.name } -func (self *mockContainerStatsWriterFactory) New( +func (self *mockStorageFactory) New( config *Config, -) (ContainerStatsWriter, error) { - mockWriter := &mockContainerStatsWriter{ +) (StorageDriver, error) { + mockWriter := &mockStorageDriver{ storageName: self.name, } return mockWriter, nil @@ -50,10 +50,10 @@ func TestContainerStatsWriterFactoryManager(t *testing.T) { wg.Add(1) go func(n string) { defer wg.Done() - factory := &mockContainerStatsWriterFactory{ + factory := &mockStorageFactory{ name: n, } - RegisterContainerStatsWriterFactory(factory) + RegisterStorage(factory) }(name) } wg.Wait() @@ -64,11 +64,11 @@ func TestContainerStatsWriterFactoryManager(t *testing.T) { } go func(n string) { defer wg.Done() - writer, err := NewContainerStatsWriter(config) + writer, err := NewStorage(config) if err != nil { t.Error(err) } - if mw, ok := writer.(*mockContainerStatsWriter); ok { + if mw, ok := writer.(*mockStorageDriver); ok { if mw.storageName != n { t.Errorf("wrong writer. should be %v, got %v", n, mw.storageName) }