Moved max_housekeeping and allow_dynamic_housekeeping flags to cadvisor.go

This commit is contained in:
Piotr Szczesniak 2015-07-21 15:50:07 +02:00
parent 5853f97295
commit 90ca5f9286
5 changed files with 61 additions and 51 deletions

View File

@ -23,6 +23,7 @@ import (
"os/signal" "os/signal"
"runtime" "runtime"
"syscall" "syscall"
"time"
"github.com/golang/glog" "github.com/golang/glog"
cadvisorHttp "github.com/google/cadvisor/http" 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 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() { func main() {
defer glog.Flush() defer glog.Flush()
flag.Parse() flag.Parse()
@ -66,7 +70,7 @@ func main() {
glog.Fatalf("Failed to create a system interface: %s", err) 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 { if err != nil {
glog.Fatalf("Failed to create a Container Manager: %s", err) glog.Fatalf("Failed to create a Container Manager: %s", err)
} }

View File

@ -39,8 +39,6 @@ import (
// Housekeeping interval. // Housekeeping interval.
var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings") 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:(.*?),.*") var cgroupPathRegExp = regexp.MustCompile(".*:devices:(.*?),.*")
@ -54,16 +52,18 @@ type containerInfo struct {
} }
type containerData struct { type containerData struct {
handler container.ContainerHandler handler container.ContainerHandler
info containerInfo info containerInfo
memoryCache *memory.InMemoryCache memoryCache *memory.InMemoryCache
lock sync.Mutex lock sync.Mutex
loadReader cpuload.CpuLoadReader loadReader cpuload.CpuLoadReader
summaryReader *summary.StatsSummary 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 maxHousekeepingInterval time.Duration
lastErrorTime time.Time allowDynamicHousekeeping bool
lastUpdatedTime time.Time
lastErrorTime time.Time
// Whether to log the usage of this container when it is updated. // Whether to log the usage of this container when it is updated.
logUsage bool logUsage bool
@ -221,7 +221,7 @@ func (c *containerData) GetProcessList(cadvisorContainer string, inHostNamespace
return processes, nil 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 { if memoryCache == nil {
return nil, fmt.Errorf("nil memory storage") return nil, fmt.Errorf("nil memory storage")
} }
@ -234,14 +234,16 @@ func newContainerData(containerName string, memoryCache *memory.InMemoryCache, h
} }
cont := &containerData{ cont := &containerData{
handler: handler, handler: handler,
memoryCache: memoryCache, memoryCache: memoryCache,
housekeepingInterval: *HousekeepingInterval, housekeepingInterval: *HousekeepingInterval,
loadReader: loadReader, maxHousekeepingInterval: maxHousekeepingInterval,
logUsage: logUsage, allowDynamicHousekeeping: allowDynamicHousekeeping,
loadAvg: -1.0, // negative value indicates uninitialized. loadReader: loadReader,
stop: make(chan bool, 1), logUsage: logUsage,
collectorManager: collectorManager, loadAvg: -1.0, // negative value indicates uninitialized.
stop: make(chan bool, 1),
collectorManager: collectorManager,
} }
cont.info.ContainerReference = ref cont.info.ContainerReference = ref
@ -260,7 +262,7 @@ func newContainerData(containerName string, memoryCache *memory.InMemoryCache, h
// Determine when the next housekeeping should occur. // Determine when the next housekeeping should occur.
func (self *containerData) nextHousekeeping(lastHousekeeping time.Time) time.Time { func (self *containerData) nextHousekeeping(lastHousekeeping time.Time) time.Time {
if *allowDynamicHousekeeping { if self.allowDynamicHousekeeping {
var empty time.Time var empty time.Time
stats, err := self.memoryCache.RecentStats(self.info.Name, empty, empty, 2) stats, err := self.memoryCache.RecentStats(self.info.Name, empty, empty, 2)
if err != nil { if err != nil {
@ -270,10 +272,10 @@ func (self *containerData) nextHousekeeping(lastHousekeeping time.Time) time.Tim
} else if len(stats) == 2 { } else if len(stats) == 2 {
// TODO(vishnuk): Use no processes as a signal. // TODO(vishnuk): Use no processes as a signal.
// Raise the interval if usage hasn't changed in the last housekeeping. // 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 self.housekeepingInterval *= 2
if self.housekeepingInterval > *maxHousekeepingInterval { if self.housekeepingInterval > self.maxHousekeepingInterval {
self.housekeepingInterval = *maxHousekeepingInterval self.housekeepingInterval = self.maxHousekeepingInterval
} }
} else if self.housekeepingInterval != *HousekeepingInterval { } else if self.housekeepingInterval != *HousekeepingInterval {
// Lower interval back to the baseline. // Lower interval back to the baseline.

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.GenericCollectorManager{}) ret, err := newContainerData(containerName, memoryCache, mockHandler, nil, false, &collector.GenericCollectorManager{}, 60*time.Second, true)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -114,7 +114,7 @@ type Manager interface {
} }
// New takes a memory storage and returns a new manager. // 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 { if memoryCache == nil {
return nil, fmt.Errorf("manager requires memory storage") return nil, fmt.Errorf("manager requires memory storage")
} }
@ -139,13 +139,15 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs) (Manager, error)
inHostNamespace = true inHostNamespace = true
} }
newManager := &manager{ newManager := &manager{
containers: make(map[namespacedContainerName]*containerData), containers: make(map[namespacedContainerName]*containerData),
quitChannels: make([]chan error, 0, 2), quitChannels: make([]chan error, 0, 2),
memoryCache: memoryCache, memoryCache: memoryCache,
fsInfo: fsInfo, fsInfo: fsInfo,
cadvisorContainer: selfContainer, cadvisorContainer: selfContainer,
inHostNamespace: inHostNamespace, inHostNamespace: inHostNamespace,
startupTime: time.Now(), startupTime: time.Now(),
maxHousekeepingInterval: maxHousekeepingInterval,
allowDynamicHousekeeping: allowDynamicHousekeeping,
} }
machineInfo, err := getMachineInfo(sysfs, fsInfo) machineInfo, err := getMachineInfo(sysfs, fsInfo)
@ -176,19 +178,21 @@ type namespacedContainerName struct {
} }
type manager struct { type manager struct {
containers map[namespacedContainerName]*containerData containers map[namespacedContainerName]*containerData
containersLock sync.RWMutex containersLock sync.RWMutex
memoryCache *memory.InMemoryCache memoryCache *memory.InMemoryCache
fsInfo fs.FsInfo fsInfo fs.FsInfo
machineInfo info.MachineInfo machineInfo info.MachineInfo
versionInfo info.VersionInfo versionInfo info.VersionInfo
quitChannels []chan error quitChannels []chan error
cadvisorContainer string cadvisorContainer string
inHostNamespace bool inHostNamespace bool
dockerContainersRegexp *regexp.Regexp dockerContainersRegexp *regexp.Regexp
loadReader cpuload.CpuLoadReader loadReader cpuload.CpuLoadReader
eventHandler events.EventManager eventHandler events.EventManager
startupTime time.Time startupTime time.Time
maxHousekeepingInterval time.Duration
allowDynamicHousekeeping bool
} }
// Start the container manager. // Start the container manager.
@ -706,7 +710,7 @@ func (m *manager) createContainer(containerName string) error {
return err return err
} }
logUsage := *logCadvisorUsage && containerName == m.cadvisorContainer 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 { if err != nil {
return err return err
} }

View File

@ -53,7 +53,7 @@ func createManagerAndAddContainers(
spec, spec,
nil, nil,
).Once() ).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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -205,7 +205,7 @@ func TestDockerContainersInfo(t *testing.T) {
} }
func TestNewNilManager(t *testing.T) { func TestNewNilManager(t *testing.T) {
_, err := New(nil, nil) _, err := New(nil, nil, 60*time.Second, true)
if err == nil { if err == nil {
t.Fatalf("Expected nil manager to return error") t.Fatalf("Expected nil manager to return error")
} }