cgroup/memory.go (128 lines of code) (raw):

package cgroup import ( "bufio" "os" "path/filepath" ) // MemorySubsystem contains the metrics and limits from the "memory" subsystem. type MemorySubsystem struct { Metadata Mem MemoryData `json:"mem"` // Memory usage by tasks in this cgroup. MemSwap MemoryData `json:"memsw"` // Memory plus swap usage by tasks in this cgroup. Kernel MemoryData `json:"kmem"` // Kernel memory used by tasks in this cgroup. KernelTCP MemoryData `json:"kmem_tcp"` // Kernel TCP buffer memory used by tasks in this cgroup. Stats MemoryStat `json:"stats"` // A wide range of memory statistics. } // MemoryData groups related memory usage metrics and limits. type MemoryData struct { Usage uint64 `json:"usage"` // Usage in bytes. MaxUsage uint64 `json:"max_usage"` // Max usage in bytes. Limit uint64 `json:"limit"` // Limit in bytes. FailCount uint64 `json:"failure_count"` // Number of times the memory limit has been reached. } // MemoryStat contains various memory statistics and accounting information // associated with a cgroup. type MemoryStat struct { // Page cache, including tmpfs (shmem), in bytes. Cache uint64 `json:"cache"` // Anonymous and swap cache, not including tmpfs (shmem), in bytes. RSS uint64 `json:"rss"` // Anonymous transparent hugepages in bytes. RSSHuge uint64 `json:"rss_huge"` // Size of memory-mapped mapped files, including tmpfs (shmem), in bytes. MappedFile uint64 `json:"mapped_file"` // Number of pages paged into memory. PagesIn uint64 `json:"pgpgin"` // Number of pages paged out of memory. PagesOut uint64 `json:"pgpgout"` // Number of times a task in the cgroup triggered a page fault. PageFaults uint64 `json:"pgfault"` // Number of times a task in the cgroup triggered a major page fault. MajorPageFaults uint64 `json:"pgmajfault"` // Swap usage in bytes. Swap uint64 `json:"swap"` // Anonymous and swap cache on active least-recently-used (LRU) list, including tmpfs (shmem), in bytes. ActiveAnon uint64 `json:"active_anon"` // Anonymous and swap cache on inactive LRU list, including tmpfs (shmem), in bytes. InactiveAnon uint64 `json:"inactive_anon"` // File-backed memory on active LRU list, in bytes. ActiveFile uint64 `json:"active_file"` // File-backed memory on inactive LRU list, in bytes. InactiveFile uint64 `json:"inactive_file"` // Memory that cannot be reclaimed, in bytes. Unevictable uint64 `json:"unevictable"` // Memory limit for the hierarchy that contains the memory cgroup, in bytes. HierarchicalMemoryLimit uint64 `json:"hierarchical_memory_limit"` // Memory plus swap limit for the hierarchy that contains the memory cgroup, in bytes. HierarchicalMemswLimit uint64 `json:"hierarchical_memsw_limit"` } // get reads metrics from the "memory" subsystem. path is the filepath to the // cgroup hierarchy to read. func (mem *MemorySubsystem) get(path string) error { if err := memoryData(path, "memory", &mem.Mem); err != nil { return err } if err := memoryData(path, "memory.memsw", &mem.MemSwap); err != nil { return err } if err := memoryData(path, "memory.kmem", &mem.Kernel); err != nil { return err } if err := memoryData(path, "memory.kmem.tcp", &mem.KernelTCP); err != nil { return err } if err := memoryStats(path, mem); err != nil { return err } return nil } func memoryData(path, prefix string, data *MemoryData) error { var err error data.Usage, err = parseUintFromFile(path, prefix+".usage_in_bytes") if err != nil { return err } data.MaxUsage, err = parseUintFromFile(path, prefix+".max_usage_in_bytes") if err != nil { return err } data.Limit, err = parseUintFromFile(path, prefix+".limit_in_bytes") if err != nil { return err } data.FailCount, err = parseUintFromFile(path, prefix+".failcnt") if err != nil { return err } return nil } func memoryStats(path string, mem *MemorySubsystem) error { f, err := os.Open(filepath.Join(path, "memory.stat")) if err != nil { if os.IsNotExist(err) { return nil } return err } defer f.Close() sc := bufio.NewScanner(f) for sc.Scan() { t, v, err := parseCgroupParamKeyValue(sc.Text()) if err != nil { return err } switch t { case "cache": mem.Stats.Cache = v case "rss": mem.Stats.RSS = v case "rss_huge": mem.Stats.RSSHuge = v case "mapped_file": mem.Stats.MappedFile = v case "pgpgin": mem.Stats.PagesIn = v case "pgpgout": mem.Stats.PagesOut = v case "pgfault": mem.Stats.PageFaults = v case "pgmajfault": mem.Stats.MajorPageFaults = v case "swap": mem.Stats.Swap = v case "active_anon": mem.Stats.ActiveAnon = v case "inactive_anon": mem.Stats.InactiveAnon = v case "active_file": mem.Stats.ActiveFile = v case "inactive_file": mem.Stats.InactiveFile = v case "unevictable": mem.Stats.Unevictable = v case "hierarchical_memory_limit": mem.Stats.HierarchicalMemoryLimit = v case "hierarchical_memsw_limit": mem.Stats.HierarchicalMemswLimit = v } } return sc.Err() }