From 90ca5f9286677d9e59ae9e5b0a442791a2551d86 Mon Sep 17 00:00:00 2001 From: Piotr Szczesniak Date: Tue, 21 Jul 2015 15:50:07 +0200 Subject: [PATCH] Moved max_housekeeping and allow_dynamic_housekeeping flags to cadvisor.go --- cadvisor.go | 6 ++++- manager/container.go | 52 ++++++++++++++++++++------------------- manager/container_test.go | 2 +- manager/manager.go | 48 +++++++++++++++++++----------------- manager/manager_test.go | 4 +-- 5 files changed, 61 insertions(+), 51 deletions(-) diff --git a/cadvisor.go b/cadvisor.go index 6bc70cb3..2fdd547d 100644 --- a/cadvisor.go +++ b/cadvisor.go @@ -23,6 +23,7 @@ import ( "os/signal" "runtime" "syscall" + "time" "github.com/golang/glog" cadvisorHttp "github.com/google/cadvisor/http" @@ -45,6 +46,9 @@ var httpDigestRealm = flag.String("http_digest_realm", "localhost", "HTTP digest var prometheusEndpoint = flag.String("prometheus_endpoint", "/metrics", "Endpoint to expose Prometheus metrics on") +var maxHousekeepingInterval = flag.Duration("max_housekeeping_interval", 60*time.Second, "Largest interval to allow between container housekeepings") +var allowDynamicHousekeeping = flag.Bool("allow_dynamic_housekeeping", true, "Whether to allow the housekeeping interval to be dynamic") + func main() { defer glog.Flush() flag.Parse() @@ -66,7 +70,7 @@ func main() { glog.Fatalf("Failed to create a system interface: %s", err) } - containerManager, err := manager.New(memoryStorage, sysFs) + containerManager, err := manager.New(memoryStorage, sysFs, *maxHousekeepingInterval, *allowDynamicHousekeeping) if err != nil { glog.Fatalf("Failed to create a Container Manager: %s", err) } diff --git a/manager/container.go b/manager/container.go index 3e53b2b4..3209e2a0 100644 --- a/manager/container.go +++ b/manager/container.go @@ -39,8 +39,6 @@ import ( // Housekeeping interval. var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings") -var maxHousekeepingInterval = flag.Duration("max_housekeeping_interval", 60*time.Second, "Largest interval to allow between container housekeepings") -var allowDynamicHousekeeping = flag.Bool("allow_dynamic_housekeeping", true, "Whether to allow the housekeeping interval to be dynamic") var cgroupPathRegExp = regexp.MustCompile(".*:devices:(.*?),.*") @@ -54,16 +52,18 @@ type containerInfo struct { } type containerData struct { - handler container.ContainerHandler - info containerInfo - memoryCache *memory.InMemoryCache - lock sync.Mutex - loadReader cpuload.CpuLoadReader - summaryReader *summary.StatsSummary - loadAvg float64 // smoothed load average seen so far. - housekeepingInterval time.Duration - lastUpdatedTime time.Time - lastErrorTime time.Time + handler container.ContainerHandler + info containerInfo + memoryCache *memory.InMemoryCache + lock sync.Mutex + loadReader cpuload.CpuLoadReader + summaryReader *summary.StatsSummary + loadAvg float64 // smoothed load average seen so far. + housekeepingInterval time.Duration + maxHousekeepingInterval time.Duration + allowDynamicHousekeeping bool + lastUpdatedTime time.Time + lastErrorTime time.Time // Whether to log the usage of this container when it is updated. logUsage bool @@ -221,7 +221,7 @@ func (c *containerData) GetProcessList(cadvisorContainer string, inHostNamespace return processes, nil } -func newContainerData(containerName string, memoryCache *memory.InMemoryCache, handler container.ContainerHandler, loadReader cpuload.CpuLoadReader, logUsage bool, collectorManager collector.CollectorManager) (*containerData, error) { +func newContainerData(containerName string, memoryCache *memory.InMemoryCache, handler container.ContainerHandler, loadReader cpuload.CpuLoadReader, logUsage bool, collectorManager collector.CollectorManager, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool) (*containerData, error) { if memoryCache == nil { return nil, fmt.Errorf("nil memory storage") } @@ -234,14 +234,16 @@ func newContainerData(containerName string, memoryCache *memory.InMemoryCache, h } cont := &containerData{ - handler: handler, - memoryCache: memoryCache, - housekeepingInterval: *HousekeepingInterval, - loadReader: loadReader, - logUsage: logUsage, - loadAvg: -1.0, // negative value indicates uninitialized. - stop: make(chan bool, 1), - collectorManager: collectorManager, + handler: handler, + memoryCache: memoryCache, + housekeepingInterval: *HousekeepingInterval, + maxHousekeepingInterval: maxHousekeepingInterval, + allowDynamicHousekeeping: allowDynamicHousekeeping, + loadReader: loadReader, + logUsage: logUsage, + loadAvg: -1.0, // negative value indicates uninitialized. + stop: make(chan bool, 1), + collectorManager: collectorManager, } cont.info.ContainerReference = ref @@ -260,7 +262,7 @@ func newContainerData(containerName string, memoryCache *memory.InMemoryCache, h // Determine when the next housekeeping should occur. func (self *containerData) nextHousekeeping(lastHousekeeping time.Time) time.Time { - if *allowDynamicHousekeeping { + if self.allowDynamicHousekeeping { var empty time.Time stats, err := self.memoryCache.RecentStats(self.info.Name, empty, empty, 2) if err != nil { @@ -270,10 +272,10 @@ func (self *containerData) nextHousekeeping(lastHousekeeping time.Time) time.Tim } else if len(stats) == 2 { // TODO(vishnuk): Use no processes as a signal. // Raise the interval if usage hasn't changed in the last housekeeping. - if stats[0].StatsEq(stats[1]) && (self.housekeepingInterval < *maxHousekeepingInterval) { + if stats[0].StatsEq(stats[1]) && (self.housekeepingInterval < self.maxHousekeepingInterval) { self.housekeepingInterval *= 2 - if self.housekeepingInterval > *maxHousekeepingInterval { - self.housekeepingInterval = *maxHousekeepingInterval + if self.housekeepingInterval > self.maxHousekeepingInterval { + self.housekeepingInterval = self.maxHousekeepingInterval } } else if self.housekeepingInterval != *HousekeepingInterval { // Lower interval back to the baseline. diff --git a/manager/container_test.go b/manager/container_test.go index 9d9bc9b3..c5bcabc6 100644 --- a/manager/container_test.go +++ b/manager/container_test.go @@ -41,7 +41,7 @@ func setupContainerData(t *testing.T, spec info.ContainerSpec) (*containerData, nil, ) memoryCache := memory.New(60, nil) - ret, err := newContainerData(containerName, memoryCache, mockHandler, nil, false, &collector.GenericCollectorManager{}) + ret, err := newContainerData(containerName, memoryCache, mockHandler, nil, false, &collector.GenericCollectorManager{}, 60*time.Second, true) if err != nil { t.Fatal(err) } diff --git a/manager/manager.go b/manager/manager.go index 62255147..761db189 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -114,7 +114,7 @@ type Manager interface { } // New takes a memory storage and returns a new manager. -func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs) (Manager, error) { +func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool) (Manager, error) { if memoryCache == nil { return nil, fmt.Errorf("manager requires memory storage") } @@ -139,13 +139,15 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs) (Manager, error) inHostNamespace = true } newManager := &manager{ - containers: make(map[namespacedContainerName]*containerData), - quitChannels: make([]chan error, 0, 2), - memoryCache: memoryCache, - fsInfo: fsInfo, - cadvisorContainer: selfContainer, - inHostNamespace: inHostNamespace, - startupTime: time.Now(), + containers: make(map[namespacedContainerName]*containerData), + quitChannels: make([]chan error, 0, 2), + memoryCache: memoryCache, + fsInfo: fsInfo, + cadvisorContainer: selfContainer, + inHostNamespace: inHostNamespace, + startupTime: time.Now(), + maxHousekeepingInterval: maxHousekeepingInterval, + allowDynamicHousekeeping: allowDynamicHousekeeping, } machineInfo, err := getMachineInfo(sysfs, fsInfo) @@ -176,19 +178,21 @@ type namespacedContainerName struct { } type manager struct { - containers map[namespacedContainerName]*containerData - containersLock sync.RWMutex - memoryCache *memory.InMemoryCache - fsInfo fs.FsInfo - machineInfo info.MachineInfo - versionInfo info.VersionInfo - quitChannels []chan error - cadvisorContainer string - inHostNamespace bool - dockerContainersRegexp *regexp.Regexp - loadReader cpuload.CpuLoadReader - eventHandler events.EventManager - startupTime time.Time + containers map[namespacedContainerName]*containerData + containersLock sync.RWMutex + memoryCache *memory.InMemoryCache + fsInfo fs.FsInfo + machineInfo info.MachineInfo + versionInfo info.VersionInfo + quitChannels []chan error + cadvisorContainer string + inHostNamespace bool + dockerContainersRegexp *regexp.Regexp + loadReader cpuload.CpuLoadReader + eventHandler events.EventManager + startupTime time.Time + maxHousekeepingInterval time.Duration + allowDynamicHousekeeping bool } // Start the container manager. @@ -706,7 +710,7 @@ func (m *manager) createContainer(containerName string) error { return err } logUsage := *logCadvisorUsage && containerName == m.cadvisorContainer - cont, err := newContainerData(containerName, m.memoryCache, handler, m.loadReader, logUsage, collectorManager) + cont, err := newContainerData(containerName, m.memoryCache, handler, m.loadReader, logUsage, collectorManager, m.maxHousekeepingInterval, m.allowDynamicHousekeeping) if err != nil { return err } diff --git a/manager/manager_test.go b/manager/manager_test.go index 9ef53d2e..b1600b88 100644 --- a/manager/manager_test.go +++ b/manager/manager_test.go @@ -53,7 +53,7 @@ func createManagerAndAddContainers( spec, nil, ).Once() - cont, err := newContainerData(name, memoryCache, mockHandler, nil, false, &collector.GenericCollectorManager{}) + cont, err := newContainerData(name, memoryCache, mockHandler, nil, false, &collector.GenericCollectorManager{}, 60*time.Second, true) if err != nil { t.Fatal(err) } @@ -205,7 +205,7 @@ func TestDockerContainersInfo(t *testing.T) { } func TestNewNilManager(t *testing.T) { - _, err := New(nil, nil) + _, err := New(nil, nil, 60*time.Second, true) if err == nil { t.Fatalf("Expected nil manager to return error") }