From 5bf787afb69e4b330d63767b53687f97232c1ac2 Mon Sep 17 00:00:00 2001 From: Dixita Narang Date: Wed, 12 Jul 2023 19:11:32 +0000 Subject: [PATCH] Adding memory.events metrics in container stats Signed-off-by: Dixita Narang --- container/libcontainer/handler.go | 20 ++++++++++++------ container/libcontainer/helpers.go | 34 +++++++++++++++++++++++++++++++ deploy/Dockerfile | 2 +- info/v1/container.go | 2 ++ 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/container/libcontainer/handler.go b/container/libcontainer/handler.go index 5a7f694776..7b11aa77bf 100644 --- a/container/libcontainer/handler.go +++ b/container/libcontainer/handler.go @@ -93,7 +93,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) { libcontainerStats := &libcontainer.Stats{ CgroupStats: cgroupStats, } - stats := newContainerStats(libcontainerStats, h.includedMetrics) + stats := newContainerStats(libcontainerStats, h.includedMetrics, h.cgroupManager.GetPaths()) if h.includedMetrics.Has(container.ProcessSchedulerMetrics) { stats.Cpu.Schedstat, err = h.schedulerStatsFromProcs() @@ -797,17 +797,26 @@ func setDiskIoStats(s *cgroups.Stats, ret *info.ContainerStats) { ret.DiskIo.IoTime = diskStatsCopy(s.BlkioStats.IoTimeRecursive) } -func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) { +func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats, cgroupPaths map[string]string) { ret.Memory.Usage = s.MemoryStats.Usage.Usage ret.Memory.MaxUsage = s.MemoryStats.Usage.MaxUsage ret.Memory.Failcnt = s.MemoryStats.Usage.Failcnt ret.Memory.KernelUsage = s.MemoryStats.KernelUsage.Usage - + klog.V(4).Info("Unable to get Process Scheduler Stats: Hi") if cgroups.IsCgroup2UnifiedMode() { ret.Memory.Cache = s.MemoryStats.Stats["file"] ret.Memory.RSS = s.MemoryStats.Stats["anon"] ret.Memory.Swap = s.MemoryStats.SwapUsage.Usage - s.MemoryStats.Usage.Usage ret.Memory.MappedFile = s.MemoryStats.Stats["file_mapped"] + testPath, ok := common.GetControllerPath(cgroupPaths, "cpu", cgroups.IsCgroup2UnifiedMode()) + if !ok { + klog.V(4).Info("Could not find cgroups CPU for container ") + } + + klog.V(4).Infof("Printing test path: %s", testPath) + + // /sys/fs/cgroup/user.slice/user-653073.slice/user@653073.service/app.slice/gnome-session-monitor.service/memory.events + ret.Memory.MemoryEvents = getMemoryEvents(cgroupPaths[""]) } else if s.MemoryStats.UseHierarchy { ret.Memory.Cache = s.MemoryStats.Stats["total_cache"] ret.Memory.RSS = s.MemoryStats.Stats["total_rss"] @@ -907,17 +916,16 @@ func setThreadsStats(s *cgroups.Stats, ret *info.ContainerStats) { } } -func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet) *info.ContainerStats { +func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet, cgroupPaths map[string]string) *info.ContainerStats { ret := &info.ContainerStats{ Timestamp: time.Now(), } - if s := libcontainerStats.CgroupStats; s != nil { setCPUStats(s, ret, includedMetrics.Has(container.PerCpuUsageMetrics)) if includedMetrics.Has(container.DiskIOMetrics) { setDiskIoStats(s, ret) } - setMemoryStats(s, ret) + setMemoryStats(s, ret, cgroupPaths) if includedMetrics.Has(container.MemoryNumaMetrics) { setMemoryNumaStats(s, ret) } diff --git a/container/libcontainer/helpers.go b/container/libcontainer/helpers.go index e535ad64c4..6af58b269d 100644 --- a/container/libcontainer/helpers.go +++ b/container/libcontainer/helpers.go @@ -15,7 +15,9 @@ package libcontainer import ( + "bufio" "fmt" + "os" info "github.com/google/cadvisor/info/v1" @@ -25,6 +27,7 @@ import ( fs "github.com/opencontainers/runc/libcontainer/cgroups/fs" fs2 "github.com/opencontainers/runc/libcontainer/cgroups/fs2" + "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" configs "github.com/opencontainers/runc/libcontainer/configs" "k8s.io/klog/v2" ) @@ -168,3 +171,34 @@ func NewCgroupManager(name string, paths map[string]string) (cgroups.Manager, er return fs.NewManager(config, paths) } + +func getMemoryEvents(path string) map[string]uint64 { + const file = "memory.events" + memoryEventsFile, err := cgroups.OpenFile(path, file, os.O_RDONLY) + if err != nil { + klog.V(4).Infof("Could not open %s/%s cgroup file: %v", path, file, err) + return nil + } + + defer memoryEventsFile.Close() + + memoryEvents := make(map[string]uint64) + sc := bufio.NewScanner(memoryEventsFile) + for sc.Scan() { + t, v, err := fscommon.ParseKeyValue(sc.Text()) + if err != nil { + klog.V(4).Infof("Could not parse line from %s/%s cgroups file: %v", path, file, err) + return nil + } + memoryEvents[t] = v + } + + klog.V(4).Infof("File Path %s/%s cgroup file: %v", path, file, err) + + if err = cgroups.WriteFile(path, file, "high 100"); err != nil { + klog.V(4).Infof("Could not open %s/%s cgroup file: %v", path, file, err) + } + + + return memoryEvents +} diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 0bd5b7deb7..49ba871e28 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -66,4 +66,4 @@ ENV CADVISOR_HEALTHCHECK_URL=http://localhost:8080/healthz HEALTHCHECK --interval=30s --timeout=3s \ CMD wget --quiet --tries=1 --spider $CADVISOR_HEALTHCHECK_URL || exit 1 -ENTRYPOINT ["/usr/bin/cadvisor", "-logtostderr"] +ENTRYPOINT ["/usr/bin/cadvisor", "-log_dir=/tmp/", "-v=5", "-logtostderr=false"] diff --git a/info/v1/container.go b/info/v1/container.go index efcfd5628e..7c6fa51fb5 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -399,6 +399,8 @@ type MemoryStats struct { // Units: Bytes. KernelUsage uint64 `json:"kernel"` + MemoryEvents map[string]uint64 `json:"memory_events"` + ContainerData MemoryStatsMemoryData `json:"container_data,omitempty"` HierarchicalData MemoryStatsMemoryData `json:"hierarchical_data,omitempty"` }