cubefs

Форк
0
277 строк · 8.1 Кб
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
package procfs
15

16
import (
17
	"bufio"
18
	"bytes"
19
	"fmt"
20
	"io"
21
	"strconv"
22
	"strings"
23

24
	"github.com/prometheus/procfs/internal/util"
25
)
26

27
// Meminfo represents memory statistics.
28
type Meminfo struct {
29
	// Total usable ram (i.e. physical ram minus a few reserved
30
	// bits and the kernel binary code)
31
	MemTotal *uint64
32
	// The sum of LowFree+HighFree
33
	MemFree *uint64
34
	// An estimate of how much memory is available for starting
35
	// new applications, without swapping. Calculated from
36
	// MemFree, SReclaimable, the size of the file LRU lists, and
37
	// the low watermarks in each zone.  The estimate takes into
38
	// account that the system needs some page cache to function
39
	// well, and that not all reclaimable slab will be
40
	// reclaimable, due to items being in use. The impact of those
41
	// factors will vary from system to system.
42
	MemAvailable *uint64
43
	// Relatively temporary storage for raw disk blocks shouldn't
44
	// get tremendously large (20MB or so)
45
	Buffers *uint64
46
	Cached  *uint64
47
	// Memory that once was swapped out, is swapped back in but
48
	// still also is in the swapfile (if memory is needed it
49
	// doesn't need to be swapped out AGAIN because it is already
50
	// in the swapfile. This saves I/O)
51
	SwapCached *uint64
52
	// Memory that has been used more recently and usually not
53
	// reclaimed unless absolutely necessary.
54
	Active *uint64
55
	// Memory which has been less recently used.  It is more
56
	// eligible to be reclaimed for other purposes
57
	Inactive     *uint64
58
	ActiveAnon   *uint64
59
	InactiveAnon *uint64
60
	ActiveFile   *uint64
61
	InactiveFile *uint64
62
	Unevictable  *uint64
63
	Mlocked      *uint64
64
	// total amount of swap space available
65
	SwapTotal *uint64
66
	// Memory which has been evicted from RAM, and is temporarily
67
	// on the disk
68
	SwapFree *uint64
69
	// Memory which is waiting to get written back to the disk
70
	Dirty *uint64
71
	// Memory which is actively being written back to the disk
72
	Writeback *uint64
73
	// Non-file backed pages mapped into userspace page tables
74
	AnonPages *uint64
75
	// files which have been mapped, such as libraries
76
	Mapped *uint64
77
	Shmem  *uint64
78
	// in-kernel data structures cache
79
	Slab *uint64
80
	// Part of Slab, that might be reclaimed, such as caches
81
	SReclaimable *uint64
82
	// Part of Slab, that cannot be reclaimed on memory pressure
83
	SUnreclaim  *uint64
84
	KernelStack *uint64
85
	// amount of memory dedicated to the lowest level of page
86
	// tables.
87
	PageTables *uint64
88
	// NFS pages sent to the server, but not yet committed to
89
	// stable storage
90
	NFSUnstable *uint64
91
	// Memory used for block device "bounce buffers"
92
	Bounce *uint64
93
	// Memory used by FUSE for temporary writeback buffers
94
	WritebackTmp *uint64
95
	// Based on the overcommit ratio ('vm.overcommit_ratio'),
96
	// this is the total amount of  memory currently available to
97
	// be allocated on the system. This limit is only adhered to
98
	// if strict overcommit accounting is enabled (mode 2 in
99
	// 'vm.overcommit_memory').
100
	// The CommitLimit is calculated with the following formula:
101
	// CommitLimit = ([total RAM pages] - [total huge TLB pages]) *
102
	//                overcommit_ratio / 100 + [total swap pages]
103
	// For example, on a system with 1G of physical RAM and 7G
104
	// of swap with a `vm.overcommit_ratio` of 30 it would
105
	// yield a CommitLimit of 7.3G.
106
	// For more details, see the memory overcommit documentation
107
	// in vm/overcommit-accounting.
108
	CommitLimit *uint64
109
	// The amount of memory presently allocated on the system.
110
	// The committed memory is a sum of all of the memory which
111
	// has been allocated by processes, even if it has not been
112
	// "used" by them as of yet. A process which malloc()'s 1G
113
	// of memory, but only touches 300M of it will show up as
114
	// using 1G. This 1G is memory which has been "committed" to
115
	// by the VM and can be used at any time by the allocating
116
	// application. With strict overcommit enabled on the system
117
	// (mode 2 in 'vm.overcommit_memory'),allocations which would
118
	// exceed the CommitLimit (detailed above) will not be permitted.
119
	// This is useful if one needs to guarantee that processes will
120
	// not fail due to lack of memory once that memory has been
121
	// successfully allocated.
122
	CommittedAS *uint64
123
	// total size of vmalloc memory area
124
	VmallocTotal *uint64
125
	// amount of vmalloc area which is used
126
	VmallocUsed *uint64
127
	// largest contiguous block of vmalloc area which is free
128
	VmallocChunk      *uint64
129
	HardwareCorrupted *uint64
130
	AnonHugePages     *uint64
131
	ShmemHugePages    *uint64
132
	ShmemPmdMapped    *uint64
133
	CmaTotal          *uint64
134
	CmaFree           *uint64
135
	HugePagesTotal    *uint64
136
	HugePagesFree     *uint64
137
	HugePagesRsvd     *uint64
138
	HugePagesSurp     *uint64
139
	Hugepagesize      *uint64
140
	DirectMap4k       *uint64
141
	DirectMap2M       *uint64
142
	DirectMap1G       *uint64
143
}
144

145
// Meminfo returns an information about current kernel/system memory statistics.
146
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
147
func (fs FS) Meminfo() (Meminfo, error) {
148
	b, err := util.ReadFileNoStat(fs.proc.Path("meminfo"))
149
	if err != nil {
150
		return Meminfo{}, err
151
	}
152

153
	m, err := parseMemInfo(bytes.NewReader(b))
154
	if err != nil {
155
		return Meminfo{}, fmt.Errorf("failed to parse meminfo: %w", err)
156
	}
157

158
	return *m, nil
159
}
160

161
func parseMemInfo(r io.Reader) (*Meminfo, error) {
162
	var m Meminfo
163
	s := bufio.NewScanner(r)
164
	for s.Scan() {
165
		// Each line has at least a name and value; we ignore the unit.
166
		fields := strings.Fields(s.Text())
167
		if len(fields) < 2 {
168
			return nil, fmt.Errorf("malformed meminfo line: %q", s.Text())
169
		}
170

171
		v, err := strconv.ParseUint(fields[1], 0, 64)
172
		if err != nil {
173
			return nil, err
174
		}
175

176
		switch fields[0] {
177
		case "MemTotal:":
178
			m.MemTotal = &v
179
		case "MemFree:":
180
			m.MemFree = &v
181
		case "MemAvailable:":
182
			m.MemAvailable = &v
183
		case "Buffers:":
184
			m.Buffers = &v
185
		case "Cached:":
186
			m.Cached = &v
187
		case "SwapCached:":
188
			m.SwapCached = &v
189
		case "Active:":
190
			m.Active = &v
191
		case "Inactive:":
192
			m.Inactive = &v
193
		case "Active(anon):":
194
			m.ActiveAnon = &v
195
		case "Inactive(anon):":
196
			m.InactiveAnon = &v
197
		case "Active(file):":
198
			m.ActiveFile = &v
199
		case "Inactive(file):":
200
			m.InactiveFile = &v
201
		case "Unevictable:":
202
			m.Unevictable = &v
203
		case "Mlocked:":
204
			m.Mlocked = &v
205
		case "SwapTotal:":
206
			m.SwapTotal = &v
207
		case "SwapFree:":
208
			m.SwapFree = &v
209
		case "Dirty:":
210
			m.Dirty = &v
211
		case "Writeback:":
212
			m.Writeback = &v
213
		case "AnonPages:":
214
			m.AnonPages = &v
215
		case "Mapped:":
216
			m.Mapped = &v
217
		case "Shmem:":
218
			m.Shmem = &v
219
		case "Slab:":
220
			m.Slab = &v
221
		case "SReclaimable:":
222
			m.SReclaimable = &v
223
		case "SUnreclaim:":
224
			m.SUnreclaim = &v
225
		case "KernelStack:":
226
			m.KernelStack = &v
227
		case "PageTables:":
228
			m.PageTables = &v
229
		case "NFS_Unstable:":
230
			m.NFSUnstable = &v
231
		case "Bounce:":
232
			m.Bounce = &v
233
		case "WritebackTmp:":
234
			m.WritebackTmp = &v
235
		case "CommitLimit:":
236
			m.CommitLimit = &v
237
		case "Committed_AS:":
238
			m.CommittedAS = &v
239
		case "VmallocTotal:":
240
			m.VmallocTotal = &v
241
		case "VmallocUsed:":
242
			m.VmallocUsed = &v
243
		case "VmallocChunk:":
244
			m.VmallocChunk = &v
245
		case "HardwareCorrupted:":
246
			m.HardwareCorrupted = &v
247
		case "AnonHugePages:":
248
			m.AnonHugePages = &v
249
		case "ShmemHugePages:":
250
			m.ShmemHugePages = &v
251
		case "ShmemPmdMapped:":
252
			m.ShmemPmdMapped = &v
253
		case "CmaTotal:":
254
			m.CmaTotal = &v
255
		case "CmaFree:":
256
			m.CmaFree = &v
257
		case "HugePages_Total:":
258
			m.HugePagesTotal = &v
259
		case "HugePages_Free:":
260
			m.HugePagesFree = &v
261
		case "HugePages_Rsvd:":
262
			m.HugePagesRsvd = &v
263
		case "HugePages_Surp:":
264
			m.HugePagesSurp = &v
265
		case "Hugepagesize:":
266
			m.Hugepagesize = &v
267
		case "DirectMap4k:":
268
			m.DirectMap4k = &v
269
		case "DirectMap2M:":
270
			m.DirectMap2M = &v
271
		case "DirectMap1G:":
272
			m.DirectMap1G = &v
273
		}
274
	}
275

276
	return &m, nil
277
}
278

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.