khenaidoo | d948f77 | 2021-08-11 17:49:24 -0400 | [diff] [blame] | 1 | // Copyright 2019 The Prometheus Authors |
| 2 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 3 | // you may not use this file except in compliance with the License. |
| 4 | // You may obtain a copy of the License at |
| 5 | // |
| 6 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 7 | // |
| 8 | // Unless required by applicable law or agreed to in writing, software |
| 9 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 11 | // See the License for the specific language governing permissions and |
| 12 | // limitations under the License. |
| 13 | |
| 14 | // +build !windows |
| 15 | |
| 16 | package procfs |
| 17 | |
| 18 | import ( |
| 19 | "fmt" |
| 20 | "io/ioutil" |
| 21 | "os" |
| 22 | "path/filepath" |
| 23 | "strings" |
| 24 | |
| 25 | "github.com/prometheus/procfs/internal/util" |
| 26 | ) |
| 27 | |
| 28 | // The VM interface is described at |
| 29 | // https://www.kernel.org/doc/Documentation/sysctl/vm.txt |
| 30 | // Each setting is exposed as a single file. |
| 31 | // Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array |
| 32 | // and numa_zonelist_order (deprecated) which is a string |
| 33 | type VM struct { |
| 34 | AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes |
| 35 | BlockDump *int64 // /proc/sys/vm/block_dump |
| 36 | CompactUnevictableAllowed *int64 // /proc/sys/vm/compact_unevictable_allowed |
| 37 | DirtyBackgroundBytes *int64 // /proc/sys/vm/dirty_background_bytes |
| 38 | DirtyBackgroundRatio *int64 // /proc/sys/vm/dirty_background_ratio |
| 39 | DirtyBytes *int64 // /proc/sys/vm/dirty_bytes |
| 40 | DirtyExpireCentisecs *int64 // /proc/sys/vm/dirty_expire_centisecs |
| 41 | DirtyRatio *int64 // /proc/sys/vm/dirty_ratio |
| 42 | DirtytimeExpireSeconds *int64 // /proc/sys/vm/dirtytime_expire_seconds |
| 43 | DirtyWritebackCentisecs *int64 // /proc/sys/vm/dirty_writeback_centisecs |
| 44 | DropCaches *int64 // /proc/sys/vm/drop_caches |
| 45 | ExtfragThreshold *int64 // /proc/sys/vm/extfrag_threshold |
| 46 | HugetlbShmGroup *int64 // /proc/sys/vm/hugetlb_shm_group |
| 47 | LaptopMode *int64 // /proc/sys/vm/laptop_mode |
| 48 | LegacyVaLayout *int64 // /proc/sys/vm/legacy_va_layout |
| 49 | LowmemReserveRatio []*int64 // /proc/sys/vm/lowmem_reserve_ratio |
| 50 | MaxMapCount *int64 // /proc/sys/vm/max_map_count |
| 51 | MemoryFailureEarlyKill *int64 // /proc/sys/vm/memory_failure_early_kill |
| 52 | MemoryFailureRecovery *int64 // /proc/sys/vm/memory_failure_recovery |
| 53 | MinFreeKbytes *int64 // /proc/sys/vm/min_free_kbytes |
| 54 | MinSlabRatio *int64 // /proc/sys/vm/min_slab_ratio |
| 55 | MinUnmappedRatio *int64 // /proc/sys/vm/min_unmapped_ratio |
| 56 | MmapMinAddr *int64 // /proc/sys/vm/mmap_min_addr |
| 57 | NrHugepages *int64 // /proc/sys/vm/nr_hugepages |
| 58 | NrHugepagesMempolicy *int64 // /proc/sys/vm/nr_hugepages_mempolicy |
| 59 | NrOvercommitHugepages *int64 // /proc/sys/vm/nr_overcommit_hugepages |
| 60 | NumaStat *int64 // /proc/sys/vm/numa_stat |
| 61 | NumaZonelistOrder string // /proc/sys/vm/numa_zonelist_order |
| 62 | OomDumpTasks *int64 // /proc/sys/vm/oom_dump_tasks |
| 63 | OomKillAllocatingTask *int64 // /proc/sys/vm/oom_kill_allocating_task |
| 64 | OvercommitKbytes *int64 // /proc/sys/vm/overcommit_kbytes |
| 65 | OvercommitMemory *int64 // /proc/sys/vm/overcommit_memory |
| 66 | OvercommitRatio *int64 // /proc/sys/vm/overcommit_ratio |
| 67 | PageCluster *int64 // /proc/sys/vm/page-cluster |
| 68 | PanicOnOom *int64 // /proc/sys/vm/panic_on_oom |
| 69 | PercpuPagelistFraction *int64 // /proc/sys/vm/percpu_pagelist_fraction |
| 70 | StatInterval *int64 // /proc/sys/vm/stat_interval |
| 71 | Swappiness *int64 // /proc/sys/vm/swappiness |
| 72 | UserReserveKbytes *int64 // /proc/sys/vm/user_reserve_kbytes |
| 73 | VfsCachePressure *int64 // /proc/sys/vm/vfs_cache_pressure |
| 74 | WatermarkBoostFactor *int64 // /proc/sys/vm/watermark_boost_factor |
| 75 | WatermarkScaleFactor *int64 // /proc/sys/vm/watermark_scale_factor |
| 76 | ZoneReclaimMode *int64 // /proc/sys/vm/zone_reclaim_mode |
| 77 | } |
| 78 | |
| 79 | // VM reads the VM statistics from the specified `proc` filesystem. |
| 80 | func (fs FS) VM() (*VM, error) { |
| 81 | path := fs.proc.Path("sys/vm") |
| 82 | file, err := os.Stat(path) |
| 83 | if err != nil { |
| 84 | return nil, err |
| 85 | } |
| 86 | if !file.Mode().IsDir() { |
| 87 | return nil, fmt.Errorf("%s is not a directory", path) |
| 88 | } |
| 89 | |
| 90 | files, err := ioutil.ReadDir(path) |
| 91 | if err != nil { |
| 92 | return nil, err |
| 93 | } |
| 94 | |
| 95 | var vm VM |
| 96 | for _, f := range files { |
| 97 | if f.IsDir() { |
| 98 | continue |
| 99 | } |
| 100 | |
| 101 | name := filepath.Join(path, f.Name()) |
| 102 | // ignore errors on read, as there are some write only |
| 103 | // in /proc/sys/vm |
| 104 | value, err := util.SysReadFile(name) |
| 105 | if err != nil { |
| 106 | continue |
| 107 | } |
| 108 | vp := util.NewValueParser(value) |
| 109 | |
| 110 | switch f.Name() { |
| 111 | case "admin_reserve_kbytes": |
| 112 | vm.AdminReserveKbytes = vp.PInt64() |
| 113 | case "block_dump": |
| 114 | vm.BlockDump = vp.PInt64() |
| 115 | case "compact_unevictable_allowed": |
| 116 | vm.CompactUnevictableAllowed = vp.PInt64() |
| 117 | case "dirty_background_bytes": |
| 118 | vm.DirtyBackgroundBytes = vp.PInt64() |
| 119 | case "dirty_background_ratio": |
| 120 | vm.DirtyBackgroundRatio = vp.PInt64() |
| 121 | case "dirty_bytes": |
| 122 | vm.DirtyBytes = vp.PInt64() |
| 123 | case "dirty_expire_centisecs": |
| 124 | vm.DirtyExpireCentisecs = vp.PInt64() |
| 125 | case "dirty_ratio": |
| 126 | vm.DirtyRatio = vp.PInt64() |
| 127 | case "dirtytime_expire_seconds": |
| 128 | vm.DirtytimeExpireSeconds = vp.PInt64() |
| 129 | case "dirty_writeback_centisecs": |
| 130 | vm.DirtyWritebackCentisecs = vp.PInt64() |
| 131 | case "drop_caches": |
| 132 | vm.DropCaches = vp.PInt64() |
| 133 | case "extfrag_threshold": |
| 134 | vm.ExtfragThreshold = vp.PInt64() |
| 135 | case "hugetlb_shm_group": |
| 136 | vm.HugetlbShmGroup = vp.PInt64() |
| 137 | case "laptop_mode": |
| 138 | vm.LaptopMode = vp.PInt64() |
| 139 | case "legacy_va_layout": |
| 140 | vm.LegacyVaLayout = vp.PInt64() |
| 141 | case "lowmem_reserve_ratio": |
| 142 | stringSlice := strings.Fields(value) |
| 143 | pint64Slice := make([]*int64, 0, len(stringSlice)) |
| 144 | for _, value := range stringSlice { |
| 145 | vp := util.NewValueParser(value) |
| 146 | pint64Slice = append(pint64Slice, vp.PInt64()) |
| 147 | } |
| 148 | vm.LowmemReserveRatio = pint64Slice |
| 149 | case "max_map_count": |
| 150 | vm.MaxMapCount = vp.PInt64() |
| 151 | case "memory_failure_early_kill": |
| 152 | vm.MemoryFailureEarlyKill = vp.PInt64() |
| 153 | case "memory_failure_recovery": |
| 154 | vm.MemoryFailureRecovery = vp.PInt64() |
| 155 | case "min_free_kbytes": |
| 156 | vm.MinFreeKbytes = vp.PInt64() |
| 157 | case "min_slab_ratio": |
| 158 | vm.MinSlabRatio = vp.PInt64() |
| 159 | case "min_unmapped_ratio": |
| 160 | vm.MinUnmappedRatio = vp.PInt64() |
| 161 | case "mmap_min_addr": |
| 162 | vm.MmapMinAddr = vp.PInt64() |
| 163 | case "nr_hugepages": |
| 164 | vm.NrHugepages = vp.PInt64() |
| 165 | case "nr_hugepages_mempolicy": |
| 166 | vm.NrHugepagesMempolicy = vp.PInt64() |
| 167 | case "nr_overcommit_hugepages": |
| 168 | vm.NrOvercommitHugepages = vp.PInt64() |
| 169 | case "numa_stat": |
| 170 | vm.NumaStat = vp.PInt64() |
| 171 | case "numa_zonelist_order": |
| 172 | vm.NumaZonelistOrder = value |
| 173 | case "oom_dump_tasks": |
| 174 | vm.OomDumpTasks = vp.PInt64() |
| 175 | case "oom_kill_allocating_task": |
| 176 | vm.OomKillAllocatingTask = vp.PInt64() |
| 177 | case "overcommit_kbytes": |
| 178 | vm.OvercommitKbytes = vp.PInt64() |
| 179 | case "overcommit_memory": |
| 180 | vm.OvercommitMemory = vp.PInt64() |
| 181 | case "overcommit_ratio": |
| 182 | vm.OvercommitRatio = vp.PInt64() |
| 183 | case "page-cluster": |
| 184 | vm.PageCluster = vp.PInt64() |
| 185 | case "panic_on_oom": |
| 186 | vm.PanicOnOom = vp.PInt64() |
| 187 | case "percpu_pagelist_fraction": |
| 188 | vm.PercpuPagelistFraction = vp.PInt64() |
| 189 | case "stat_interval": |
| 190 | vm.StatInterval = vp.PInt64() |
| 191 | case "swappiness": |
| 192 | vm.Swappiness = vp.PInt64() |
| 193 | case "user_reserve_kbytes": |
| 194 | vm.UserReserveKbytes = vp.PInt64() |
| 195 | case "vfs_cache_pressure": |
| 196 | vm.VfsCachePressure = vp.PInt64() |
| 197 | case "watermark_boost_factor": |
| 198 | vm.WatermarkBoostFactor = vp.PInt64() |
| 199 | case "watermark_scale_factor": |
| 200 | vm.WatermarkScaleFactor = vp.PInt64() |
| 201 | case "zone_reclaim_mode": |
| 202 | vm.ZoneReclaimMode = vp.PInt64() |
| 203 | } |
| 204 | if err := vp.Err(); err != nil { |
| 205 | return nil, err |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | return &vm, nil |
| 210 | } |