blob: 0b9bb6796b3d4a121a09c0e4d10bc1d2dce0ff31 [file] [log] [blame]
khenaidoo26721882021-08-11 17:42:52 -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
14// +build !windows
15
16package procfs
17
18import (
19 "bytes"
20 "fmt"
21 "io/ioutil"
22 "regexp"
23 "strings"
24
25 "github.com/prometheus/procfs/internal/util"
26)
27
28// Zoneinfo holds info parsed from /proc/zoneinfo.
29type Zoneinfo struct {
30 Node string
31 Zone string
32 NrFreePages *int64
33 Min *int64
34 Low *int64
35 High *int64
36 Scanned *int64
37 Spanned *int64
38 Present *int64
39 Managed *int64
40 NrActiveAnon *int64
41 NrInactiveAnon *int64
42 NrIsolatedAnon *int64
43 NrAnonPages *int64
44 NrAnonTransparentHugepages *int64
45 NrActiveFile *int64
46 NrInactiveFile *int64
47 NrIsolatedFile *int64
48 NrFilePages *int64
49 NrSlabReclaimable *int64
50 NrSlabUnreclaimable *int64
51 NrMlockStack *int64
52 NrKernelStack *int64
53 NrMapped *int64
54 NrDirty *int64
55 NrWriteback *int64
56 NrUnevictable *int64
57 NrShmem *int64
58 NrDirtied *int64
59 NrWritten *int64
60 NumaHit *int64
61 NumaMiss *int64
62 NumaForeign *int64
63 NumaInterleave *int64
64 NumaLocal *int64
65 NumaOther *int64
66 Protection []*int64
67}
68
69var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`)
70
71// Zoneinfo parses an zoneinfo-file (/proc/zoneinfo) and returns a slice of
72// structs containing the relevant info. More information available here:
73// https://www.kernel.org/doc/Documentation/sysctl/vm.txt
74func (fs FS) Zoneinfo() ([]Zoneinfo, error) {
75 data, err := ioutil.ReadFile(fs.proc.Path("zoneinfo"))
76 if err != nil {
77 return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)
78 }
79 zoneinfo, err := parseZoneinfo(data)
80 if err != nil {
81 return nil, fmt.Errorf("error parsing zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)
82 }
83 return zoneinfo, nil
84}
85
86func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) {
87
88 zoneinfo := []Zoneinfo{}
89
90 zoneinfoBlocks := bytes.Split(zoneinfoData, []byte("\nNode"))
91 for _, block := range zoneinfoBlocks {
92 var zoneinfoElement Zoneinfo
93 lines := strings.Split(string(block), "\n")
94 for _, line := range lines {
95
96 if nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil {
97 zoneinfoElement.Node = nodeZone[1]
98 zoneinfoElement.Zone = nodeZone[2]
99 continue
100 }
101 if strings.HasPrefix(strings.TrimSpace(line), "per-node stats") {
102 zoneinfoElement.Zone = ""
103 continue
104 }
105 parts := strings.Fields(strings.TrimSpace(line))
106 if len(parts) < 2 {
107 continue
108 }
109 vp := util.NewValueParser(parts[1])
110 switch parts[0] {
111 case "nr_free_pages":
112 zoneinfoElement.NrFreePages = vp.PInt64()
113 case "min":
114 zoneinfoElement.Min = vp.PInt64()
115 case "low":
116 zoneinfoElement.Low = vp.PInt64()
117 case "high":
118 zoneinfoElement.High = vp.PInt64()
119 case "scanned":
120 zoneinfoElement.Scanned = vp.PInt64()
121 case "spanned":
122 zoneinfoElement.Spanned = vp.PInt64()
123 case "present":
124 zoneinfoElement.Present = vp.PInt64()
125 case "managed":
126 zoneinfoElement.Managed = vp.PInt64()
127 case "nr_active_anon":
128 zoneinfoElement.NrActiveAnon = vp.PInt64()
129 case "nr_inactive_anon":
130 zoneinfoElement.NrInactiveAnon = vp.PInt64()
131 case "nr_isolated_anon":
132 zoneinfoElement.NrIsolatedAnon = vp.PInt64()
133 case "nr_anon_pages":
134 zoneinfoElement.NrAnonPages = vp.PInt64()
135 case "nr_anon_transparent_hugepages":
136 zoneinfoElement.NrAnonTransparentHugepages = vp.PInt64()
137 case "nr_active_file":
138 zoneinfoElement.NrActiveFile = vp.PInt64()
139 case "nr_inactive_file":
140 zoneinfoElement.NrInactiveFile = vp.PInt64()
141 case "nr_isolated_file":
142 zoneinfoElement.NrIsolatedFile = vp.PInt64()
143 case "nr_file_pages":
144 zoneinfoElement.NrFilePages = vp.PInt64()
145 case "nr_slab_reclaimable":
146 zoneinfoElement.NrSlabReclaimable = vp.PInt64()
147 case "nr_slab_unreclaimable":
148 zoneinfoElement.NrSlabUnreclaimable = vp.PInt64()
149 case "nr_mlock_stack":
150 zoneinfoElement.NrMlockStack = vp.PInt64()
151 case "nr_kernel_stack":
152 zoneinfoElement.NrKernelStack = vp.PInt64()
153 case "nr_mapped":
154 zoneinfoElement.NrMapped = vp.PInt64()
155 case "nr_dirty":
156 zoneinfoElement.NrDirty = vp.PInt64()
157 case "nr_writeback":
158 zoneinfoElement.NrWriteback = vp.PInt64()
159 case "nr_unevictable":
160 zoneinfoElement.NrUnevictable = vp.PInt64()
161 case "nr_shmem":
162 zoneinfoElement.NrShmem = vp.PInt64()
163 case "nr_dirtied":
164 zoneinfoElement.NrDirtied = vp.PInt64()
165 case "nr_written":
166 zoneinfoElement.NrWritten = vp.PInt64()
167 case "numa_hit":
168 zoneinfoElement.NumaHit = vp.PInt64()
169 case "numa_miss":
170 zoneinfoElement.NumaMiss = vp.PInt64()
171 case "numa_foreign":
172 zoneinfoElement.NumaForeign = vp.PInt64()
173 case "numa_interleave":
174 zoneinfoElement.NumaInterleave = vp.PInt64()
175 case "numa_local":
176 zoneinfoElement.NumaLocal = vp.PInt64()
177 case "numa_other":
178 zoneinfoElement.NumaOther = vp.PInt64()
179 case "protection:":
180 protectionParts := strings.Split(line, ":")
181 protectionValues := strings.Replace(protectionParts[1], "(", "", 1)
182 protectionValues = strings.Replace(protectionValues, ")", "", 1)
183 protectionValues = strings.TrimSpace(protectionValues)
184 protectionStringMap := strings.Split(protectionValues, ", ")
185 val, err := util.ParsePInt64s(protectionStringMap)
186 if err == nil {
187 zoneinfoElement.Protection = val
188 }
189 }
190
191 }
192
193 zoneinfo = append(zoneinfo, zoneinfoElement)
194 }
195 return zoneinfo, nil
196}