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 16package procfs 17 18import ( 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 33type 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. 80func (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} 211