blob: 51c49d89e81b5252ae06bc1f0ee5d3d0c08585b1 [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001// 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
Abhay Kumara2ae5992025-11-10 14:02:24 +000014//go:build !windows
khenaidood948f772021-08-11 17:49:24 -040015// +build !windows
16
17package procfs
18
19import (
20 "fmt"
khenaidood948f772021-08-11 17:49:24 -040021 "os"
22 "path/filepath"
23 "strings"
24
25 "github.com/prometheus/procfs/internal/util"
26)
27
28// The VM interface is described at
Abhay Kumara2ae5992025-11-10 14:02:24 +000029//
30// https://www.kernel.org/doc/Documentation/sysctl/vm.txt
31//
khenaidood948f772021-08-11 17:49:24 -040032// Each setting is exposed as a single file.
33// Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array
Abhay Kumara2ae5992025-11-10 14:02:24 +000034// and numa_zonelist_order (deprecated) which is a string.
khenaidood948f772021-08-11 17:49:24 -040035type VM struct {
36 AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes
37 BlockDump *int64 // /proc/sys/vm/block_dump
38 CompactUnevictableAllowed *int64 // /proc/sys/vm/compact_unevictable_allowed
39 DirtyBackgroundBytes *int64 // /proc/sys/vm/dirty_background_bytes
40 DirtyBackgroundRatio *int64 // /proc/sys/vm/dirty_background_ratio
41 DirtyBytes *int64 // /proc/sys/vm/dirty_bytes
42 DirtyExpireCentisecs *int64 // /proc/sys/vm/dirty_expire_centisecs
43 DirtyRatio *int64 // /proc/sys/vm/dirty_ratio
44 DirtytimeExpireSeconds *int64 // /proc/sys/vm/dirtytime_expire_seconds
45 DirtyWritebackCentisecs *int64 // /proc/sys/vm/dirty_writeback_centisecs
46 DropCaches *int64 // /proc/sys/vm/drop_caches
47 ExtfragThreshold *int64 // /proc/sys/vm/extfrag_threshold
48 HugetlbShmGroup *int64 // /proc/sys/vm/hugetlb_shm_group
49 LaptopMode *int64 // /proc/sys/vm/laptop_mode
50 LegacyVaLayout *int64 // /proc/sys/vm/legacy_va_layout
51 LowmemReserveRatio []*int64 // /proc/sys/vm/lowmem_reserve_ratio
52 MaxMapCount *int64 // /proc/sys/vm/max_map_count
53 MemoryFailureEarlyKill *int64 // /proc/sys/vm/memory_failure_early_kill
54 MemoryFailureRecovery *int64 // /proc/sys/vm/memory_failure_recovery
55 MinFreeKbytes *int64 // /proc/sys/vm/min_free_kbytes
56 MinSlabRatio *int64 // /proc/sys/vm/min_slab_ratio
57 MinUnmappedRatio *int64 // /proc/sys/vm/min_unmapped_ratio
58 MmapMinAddr *int64 // /proc/sys/vm/mmap_min_addr
59 NrHugepages *int64 // /proc/sys/vm/nr_hugepages
60 NrHugepagesMempolicy *int64 // /proc/sys/vm/nr_hugepages_mempolicy
61 NrOvercommitHugepages *int64 // /proc/sys/vm/nr_overcommit_hugepages
62 NumaStat *int64 // /proc/sys/vm/numa_stat
63 NumaZonelistOrder string // /proc/sys/vm/numa_zonelist_order
64 OomDumpTasks *int64 // /proc/sys/vm/oom_dump_tasks
65 OomKillAllocatingTask *int64 // /proc/sys/vm/oom_kill_allocating_task
66 OvercommitKbytes *int64 // /proc/sys/vm/overcommit_kbytes
67 OvercommitMemory *int64 // /proc/sys/vm/overcommit_memory
68 OvercommitRatio *int64 // /proc/sys/vm/overcommit_ratio
69 PageCluster *int64 // /proc/sys/vm/page-cluster
70 PanicOnOom *int64 // /proc/sys/vm/panic_on_oom
71 PercpuPagelistFraction *int64 // /proc/sys/vm/percpu_pagelist_fraction
72 StatInterval *int64 // /proc/sys/vm/stat_interval
73 Swappiness *int64 // /proc/sys/vm/swappiness
74 UserReserveKbytes *int64 // /proc/sys/vm/user_reserve_kbytes
75 VfsCachePressure *int64 // /proc/sys/vm/vfs_cache_pressure
76 WatermarkBoostFactor *int64 // /proc/sys/vm/watermark_boost_factor
77 WatermarkScaleFactor *int64 // /proc/sys/vm/watermark_scale_factor
78 ZoneReclaimMode *int64 // /proc/sys/vm/zone_reclaim_mode
79}
80
81// VM reads the VM statistics from the specified `proc` filesystem.
82func (fs FS) VM() (*VM, error) {
83 path := fs.proc.Path("sys/vm")
84 file, err := os.Stat(path)
85 if err != nil {
86 return nil, err
87 }
88 if !file.Mode().IsDir() {
Abhay Kumara2ae5992025-11-10 14:02:24 +000089 return nil, fmt.Errorf("%w: %s is not a directory", ErrFileRead, path)
khenaidood948f772021-08-11 17:49:24 -040090 }
91
Abhay Kumara2ae5992025-11-10 14:02:24 +000092 files, err := os.ReadDir(path)
khenaidood948f772021-08-11 17:49:24 -040093 if err != nil {
94 return nil, err
95 }
96
97 var vm VM
98 for _, f := range files {
99 if f.IsDir() {
100 continue
101 }
102
103 name := filepath.Join(path, f.Name())
104 // ignore errors on read, as there are some write only
105 // in /proc/sys/vm
106 value, err := util.SysReadFile(name)
107 if err != nil {
108 continue
109 }
110 vp := util.NewValueParser(value)
111
112 switch f.Name() {
113 case "admin_reserve_kbytes":
114 vm.AdminReserveKbytes = vp.PInt64()
115 case "block_dump":
116 vm.BlockDump = vp.PInt64()
117 case "compact_unevictable_allowed":
118 vm.CompactUnevictableAllowed = vp.PInt64()
119 case "dirty_background_bytes":
120 vm.DirtyBackgroundBytes = vp.PInt64()
121 case "dirty_background_ratio":
122 vm.DirtyBackgroundRatio = vp.PInt64()
123 case "dirty_bytes":
124 vm.DirtyBytes = vp.PInt64()
125 case "dirty_expire_centisecs":
126 vm.DirtyExpireCentisecs = vp.PInt64()
127 case "dirty_ratio":
128 vm.DirtyRatio = vp.PInt64()
129 case "dirtytime_expire_seconds":
130 vm.DirtytimeExpireSeconds = vp.PInt64()
131 case "dirty_writeback_centisecs":
132 vm.DirtyWritebackCentisecs = vp.PInt64()
133 case "drop_caches":
134 vm.DropCaches = vp.PInt64()
135 case "extfrag_threshold":
136 vm.ExtfragThreshold = vp.PInt64()
137 case "hugetlb_shm_group":
138 vm.HugetlbShmGroup = vp.PInt64()
139 case "laptop_mode":
140 vm.LaptopMode = vp.PInt64()
141 case "legacy_va_layout":
142 vm.LegacyVaLayout = vp.PInt64()
143 case "lowmem_reserve_ratio":
144 stringSlice := strings.Fields(value)
145 pint64Slice := make([]*int64, 0, len(stringSlice))
146 for _, value := range stringSlice {
147 vp := util.NewValueParser(value)
148 pint64Slice = append(pint64Slice, vp.PInt64())
149 }
150 vm.LowmemReserveRatio = pint64Slice
151 case "max_map_count":
152 vm.MaxMapCount = vp.PInt64()
153 case "memory_failure_early_kill":
154 vm.MemoryFailureEarlyKill = vp.PInt64()
155 case "memory_failure_recovery":
156 vm.MemoryFailureRecovery = vp.PInt64()
157 case "min_free_kbytes":
158 vm.MinFreeKbytes = vp.PInt64()
159 case "min_slab_ratio":
160 vm.MinSlabRatio = vp.PInt64()
161 case "min_unmapped_ratio":
162 vm.MinUnmappedRatio = vp.PInt64()
163 case "mmap_min_addr":
164 vm.MmapMinAddr = vp.PInt64()
165 case "nr_hugepages":
166 vm.NrHugepages = vp.PInt64()
167 case "nr_hugepages_mempolicy":
168 vm.NrHugepagesMempolicy = vp.PInt64()
169 case "nr_overcommit_hugepages":
170 vm.NrOvercommitHugepages = vp.PInt64()
171 case "numa_stat":
172 vm.NumaStat = vp.PInt64()
173 case "numa_zonelist_order":
174 vm.NumaZonelistOrder = value
175 case "oom_dump_tasks":
176 vm.OomDumpTasks = vp.PInt64()
177 case "oom_kill_allocating_task":
178 vm.OomKillAllocatingTask = vp.PInt64()
179 case "overcommit_kbytes":
180 vm.OvercommitKbytes = vp.PInt64()
181 case "overcommit_memory":
182 vm.OvercommitMemory = vp.PInt64()
183 case "overcommit_ratio":
184 vm.OvercommitRatio = vp.PInt64()
185 case "page-cluster":
186 vm.PageCluster = vp.PInt64()
187 case "panic_on_oom":
188 vm.PanicOnOom = vp.PInt64()
189 case "percpu_pagelist_fraction":
190 vm.PercpuPagelistFraction = vp.PInt64()
191 case "stat_interval":
192 vm.StatInterval = vp.PInt64()
193 case "swappiness":
194 vm.Swappiness = vp.PInt64()
195 case "user_reserve_kbytes":
196 vm.UserReserveKbytes = vp.PInt64()
197 case "vfs_cache_pressure":
198 vm.VfsCachePressure = vp.PInt64()
199 case "watermark_boost_factor":
200 vm.WatermarkBoostFactor = vp.PInt64()
201 case "watermark_scale_factor":
202 vm.WatermarkScaleFactor = vp.PInt64()
203 case "zone_reclaim_mode":
204 vm.ZoneReclaimMode = vp.PInt64()
205 }
206 if err := vp.Err(); err != nil {
207 return nil, err
208 }
209 }
210
211 return &vm, nil
212}