diff --git a/metric/system/cgroup/reader.go b/metric/system/cgroup/reader.go index 7f5a49700..bba0e175a 100644 --- a/metric/system/cgroup/reader.go +++ b/metric/system/cgroup/reader.go @@ -24,6 +24,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/elastic-agent-system-metrics/metric/system/cgroup/cgv1" @@ -78,6 +79,12 @@ type mount struct { fullPath string // Absolute path to the cgroup. It's the mountpoint joined with the path. } +// pathListWithTime +type pathListWithTime struct { + added time.Time + pathList PathList +} + // Reader reads cgroup metrics and limits. type Reader struct { // Mountpoint of the root filesystem. Defaults to / if not set. This can be @@ -87,7 +94,7 @@ type Reader struct { cgroupsHierarchyOverride string cgroupMountpoints Mountpoints // Mountpoints for each subsystem (e.g. cpu, cpuacct, memory, blkio). - // Cache to map known v2 cgroup controllerPaths to PathList. + // Cache to map known v2 cgroup controllerPaths to pathListWithTime. v2ControllerPathCache sync.Map } diff --git a/metric/system/cgroup/util.go b/metric/system/cgroup/util.go index 601b6910c..4f874a4ec 100644 --- a/metric/system/cgroup/util.go +++ b/metric/system/cgroup/util.go @@ -26,6 +26,7 @@ import ( "path/filepath" "strconv" "strings" + "time" "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/elastic-agent-system-metrics/metric/system/resolve" @@ -277,12 +278,20 @@ the container as /sys/fs/cgroup/unified and start the system module with the hos controllerPath = r.rootfsMountpoint.ResolveHostFS(filepath.Join("/sys/fs/cgroup/unified", path)) } + // Check if there is an entry for controllerPath already cached. if tmp, ok := r.v2ControllerPathCache.Load(controllerPath); ok { - pathList, ok := tmp.(PathList) + cacheEntry, ok := tmp.(pathListWithTime) if ok { - cPaths.V2 = pathList.V2 - continue + // If the cached entry for controllerPath is not older than 5 minutes, + // return the cached entry. + if time.Since(cacheEntry.added) < time.Duration(5*time.Minute) { + cPaths.V2 = cacheEntry.pathList.V2 + continue + } } + // Consider the existing entry for controllerPath invalid. The entry can + // (1) not be casted to pathListWithTime or (2) is older than 5 minutes. + r.v2ControllerPathCache.Delete(controllerPath) } cgpaths, err := ioutil.ReadDir(controllerPath) @@ -297,7 +306,10 @@ the container as /sys/fs/cgroup/unified and start the system module with the hos cPaths.V2[controllerName] = ControllerPath{ControllerPath: path, FullPath: controllerPath, IsV2: true} } } - r.v2ControllerPathCache.Store(controllerPath, cPaths) + r.v2ControllerPathCache.Store(controllerPath, pathListWithTime{ + added: time.Now(), + pathList: cPaths, + }) // cgroup v1 } else { subsystems := strings.Split(fields[1], ",")