github.com/elastic/gosigar@v0.14.3/cgroup/memory.go (about) 1 package cgroup 2 3 import ( 4 "bufio" 5 "os" 6 "path/filepath" 7 ) 8 9 // MemorySubsystem contains the metrics and limits from the "memory" subsystem. 10 type MemorySubsystem struct { 11 Metadata 12 Mem MemoryData `json:"mem"` // Memory usage by tasks in this cgroup. 13 MemSwap MemoryData `json:"memsw"` // Memory plus swap usage by tasks in this cgroup. 14 Kernel MemoryData `json:"kmem"` // Kernel memory used by tasks in this cgroup. 15 KernelTCP MemoryData `json:"kmem_tcp"` // Kernel TCP buffer memory used by tasks in this cgroup. 16 Stats MemoryStat `json:"stats"` // A wide range of memory statistics. 17 } 18 19 // MemoryData groups related memory usage metrics and limits. 20 type MemoryData struct { 21 Usage uint64 `json:"usage"` // Usage in bytes. 22 MaxUsage uint64 `json:"max_usage"` // Max usage in bytes. 23 Limit uint64 `json:"limit"` // Limit in bytes. 24 FailCount uint64 `json:"failure_count"` // Number of times the memory limit has been reached. 25 } 26 27 // MemoryStat contains various memory statistics and accounting information 28 // associated with a cgroup. 29 type MemoryStat struct { 30 // Page cache, including tmpfs (shmem), in bytes. 31 Cache uint64 `json:"cache"` 32 // Anonymous and swap cache, not including tmpfs (shmem), in bytes. 33 RSS uint64 `json:"rss"` 34 // Anonymous transparent hugepages in bytes. 35 RSSHuge uint64 `json:"rss_huge"` 36 // Size of memory-mapped mapped files, including tmpfs (shmem), in bytes. 37 MappedFile uint64 `json:"mapped_file"` 38 // Number of pages paged into memory. 39 PagesIn uint64 `json:"pgpgin"` 40 // Number of pages paged out of memory. 41 PagesOut uint64 `json:"pgpgout"` 42 // Number of times a task in the cgroup triggered a page fault. 43 PageFaults uint64 `json:"pgfault"` 44 // Number of times a task in the cgroup triggered a major page fault. 45 MajorPageFaults uint64 `json:"pgmajfault"` 46 // Swap usage in bytes. 47 Swap uint64 `json:"swap"` 48 // Anonymous and swap cache on active least-recently-used (LRU) list, including tmpfs (shmem), in bytes. 49 ActiveAnon uint64 `json:"active_anon"` 50 // Anonymous and swap cache on inactive LRU list, including tmpfs (shmem), in bytes. 51 InactiveAnon uint64 `json:"inactive_anon"` 52 // File-backed memory on active LRU list, in bytes. 53 ActiveFile uint64 `json:"active_file"` 54 // File-backed memory on inactive LRU list, in bytes. 55 InactiveFile uint64 `json:"inactive_file"` 56 // Memory that cannot be reclaimed, in bytes. 57 Unevictable uint64 `json:"unevictable"` 58 // Memory limit for the hierarchy that contains the memory cgroup, in bytes. 59 HierarchicalMemoryLimit uint64 `json:"hierarchical_memory_limit"` 60 // Memory plus swap limit for the hierarchy that contains the memory cgroup, in bytes. 61 HierarchicalMemswLimit uint64 `json:"hierarchical_memsw_limit"` 62 } 63 64 // get reads metrics from the "memory" subsystem. path is the filepath to the 65 // cgroup hierarchy to read. 66 func (mem *MemorySubsystem) get(path string) error { 67 if err := memoryData(path, "memory", &mem.Mem); err != nil { 68 return err 69 } 70 71 if err := memoryData(path, "memory.memsw", &mem.MemSwap); err != nil { 72 return err 73 } 74 75 if err := memoryData(path, "memory.kmem", &mem.Kernel); err != nil { 76 return err 77 } 78 79 if err := memoryData(path, "memory.kmem.tcp", &mem.KernelTCP); err != nil { 80 return err 81 } 82 83 if err := memoryStats(path, mem); err != nil { 84 return err 85 } 86 87 return nil 88 } 89 90 func memoryData(path, prefix string, data *MemoryData) error { 91 var err error 92 data.Usage, err = parseUintFromFile(path, prefix+".usage_in_bytes") 93 if err != nil { 94 return err 95 } 96 97 data.MaxUsage, err = parseUintFromFile(path, prefix+".max_usage_in_bytes") 98 if err != nil { 99 return err 100 } 101 102 data.Limit, err = parseUintFromFile(path, prefix+".limit_in_bytes") 103 if err != nil { 104 return err 105 } 106 107 data.FailCount, err = parseUintFromFile(path, prefix+".failcnt") 108 if err != nil { 109 return err 110 } 111 112 return nil 113 } 114 115 func memoryStats(path string, mem *MemorySubsystem) error { 116 f, err := os.Open(filepath.Join(path, "memory.stat")) 117 if err != nil { 118 if os.IsNotExist(err) { 119 return nil 120 } 121 return err 122 } 123 defer f.Close() 124 125 sc := bufio.NewScanner(f) 126 for sc.Scan() { 127 t, v, err := parseCgroupParamKeyValue(sc.Text()) 128 if err != nil { 129 return err 130 } 131 switch t { 132 case "cache": 133 mem.Stats.Cache = v 134 case "rss": 135 mem.Stats.RSS = v 136 case "rss_huge": 137 mem.Stats.RSSHuge = v 138 case "mapped_file": 139 mem.Stats.MappedFile = v 140 case "pgpgin": 141 mem.Stats.PagesIn = v 142 case "pgpgout": 143 mem.Stats.PagesOut = v 144 case "pgfault": 145 mem.Stats.PageFaults = v 146 case "pgmajfault": 147 mem.Stats.MajorPageFaults = v 148 case "swap": 149 mem.Stats.Swap = v 150 case "active_anon": 151 mem.Stats.ActiveAnon = v 152 case "inactive_anon": 153 mem.Stats.InactiveAnon = v 154 case "active_file": 155 mem.Stats.ActiveFile = v 156 case "inactive_file": 157 mem.Stats.InactiveFile = v 158 case "unevictable": 159 mem.Stats.Unevictable = v 160 case "hierarchical_memory_limit": 161 mem.Stats.HierarchicalMemoryLimit = v 162 case "hierarchical_memsw_limit": 163 mem.Stats.HierarchicalMemswLimit = v 164 } 165 } 166 167 return sc.Err() 168 }