From e2717d8bb7d095702b5f7469a5f340fb1497a7dd Mon Sep 17 00:00:00 2001 From: Vishnu kannan Date: Mon, 14 Mar 2016 12:10:57 -0700 Subject: [PATCH] Avoid collecting network stats for non root cgroups in raw handler. Signed-off-by: Vishnu kannan --- cadvisor.go | 5 ++-- container/libcontainer/helpers.go | 43 ++++++++++++++++--------------- container/raw/handler.go | 19 +++++++++++--- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/cadvisor.go b/cadvisor.go index b67c0720..f21503b8 100644 --- a/cadvisor.go +++ b/cadvisor.go @@ -56,7 +56,8 @@ var enableProfiling = flag.Bool("profiling", false, "Enable profiling via web in var ( // Metrics to be ignored. - ignoreMetrics metricSetValue = metricSetValue{container.MetricSet{}} + // Tcp metrics are ignored by default. + ignoreMetrics metricSetValue = metricSetValue{container.MetricSet{container.NetworkTcpUsageMetrics: struct{}{}}} // List of metrics that can be ignored. ignoreWhitelist = container.MetricSet{ @@ -87,8 +88,6 @@ func (ml *metricSetValue) Set(value string) error { func init() { flag.Var(&ignoreMetrics, "disable_metrics", "comma-separated list of metrics to be disabled. Options are `disk`, `network`, `tcp`. Note: tcp is disabled by default due to high CPU usage.") - // Tcp metrics are ignored by default. - flag.Set("disable_metrics", "tcp") } func main() { diff --git a/container/libcontainer/helpers.go b/container/libcontainer/helpers.go index 674ecdb6..bcf26586 100644 --- a/container/libcontainer/helpers.go +++ b/container/libcontainer/helpers.go @@ -92,29 +92,30 @@ func GetStats(cgroupManager cgroups.Manager, rootFs string, pid int, ignoreMetri stats := toContainerStats(libcontainerStats) // If we know the pid then get network stats from /proc//net/dev - if pid > 0 { - if !ignoreMetrics.Has(container.NetworkUsageMetrics) { - netStats, err := networkStatsFromProc(rootFs, pid) - if err != nil { - glog.V(2).Infof("Unable to get network stats from pid %d: %v", pid, err) - } else { - stats.Network.Interfaces = append(stats.Network.Interfaces, netStats...) - } + if pid == 0 { + return stats, nil + } + if !ignoreMetrics.Has(container.NetworkUsageMetrics) { + netStats, err := networkStatsFromProc(rootFs, pid) + if err != nil { + glog.V(2).Infof("Unable to get network stats from pid %d: %v", pid, err) + } else { + stats.Network.Interfaces = append(stats.Network.Interfaces, netStats...) + } + } + if !ignoreMetrics.Has(container.NetworkTcpUsageMetrics) { + t, err := tcpStatsFromProc(rootFs, pid, "net/tcp") + if err != nil { + glog.V(2).Infof("Unable to get tcp stats from pid %d: %v", pid, err) + } else { + stats.Network.Tcp = t } - if !ignoreMetrics.Has(container.NetworkTcpUsageMetrics) { - t, err := tcpStatsFromProc(rootFs, pid, "net/tcp") - if err != nil { - glog.V(2).Infof("Unable to get tcp stats from pid %d: %v", pid, err) - } else { - stats.Network.Tcp = t - } - t6, err := tcpStatsFromProc(rootFs, pid, "net/tcp6") - if err != nil { - glog.V(2).Infof("Unable to get tcp6 stats from pid %d: %v", pid, err) - } else { - stats.Network.Tcp6 = t6 - } + t6, err := tcpStatsFromProc(rootFs, pid, "net/tcp6") + if err != nil { + glog.V(2).Infof("Unable to get tcp6 stats from pid %d: %v", pid, err) + } else { + stats.Network.Tcp6 = t6 } } diff --git a/container/raw/handler.go b/container/raw/handler.go index 7ecfb63f..acaaa2a7 100644 --- a/container/raw/handler.go +++ b/container/raw/handler.go @@ -18,7 +18,6 @@ package raw import ( "fmt" "io/ioutil" - "os" "path" "strings" @@ -62,6 +61,8 @@ type rawContainerHandler struct { // Metrics to be ignored. ignoreMetrics container.MetricSet + + pid int } func (self *rawContainerHandler) GetCgroupPaths() map[string]string { @@ -88,6 +89,10 @@ func (self *rawContainerHandler) HasFilesystem() bool { return false } +func isRootCgroup(name string) bool { + return name == "/" +} + func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, ignoreMetrics container.MetricSet) (container.ContainerHandler, error) { cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name) @@ -112,6 +117,11 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu } } + pid := 0 + if isRootCgroup(name) { + pid = 1 + } + return &rawContainerHandler{ name: name, cgroupSubsystems: cgroupSubsystems, @@ -124,6 +134,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu watcher: watcher, rootFs: rootFs, ignoreMetrics: ignoreMetrics, + pid: pid, }, nil } @@ -136,7 +147,7 @@ func (self *rawContainerHandler) ContainerReference() (info.ContainerReference, func (self *rawContainerHandler) GetRootNetworkDevices() ([]info.NetInfo, error) { nd := []info.NetInfo{} - if self.name == "/" { + if isRootCgroup(self.name) { mi, err := self.machineInfoFactory.GetMachineInfo() if err != nil { return nd, err @@ -158,7 +169,7 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) { func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error { // Get Filesystem information only for the root cgroup. - if self.name == "/" { + if isRootCgroup(self.name) { filesystems, err := self.fsInfo.GetGlobalFsInfo() if err != nil { return err @@ -221,7 +232,7 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error { } func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) { - stats, err := libcontainer.GetStats(self.cgroupManager, self.rootFs, os.Getpid(), self.ignoreMetrics) + stats, err := libcontainer.GetStats(self.cgroupManager, self.rootFs, self.pid, self.ignoreMetrics) if err != nil { return stats, err }