VictoriaMetrics/vendor/github.com/prometheus/procfs/meminfo.go

278 lines
8.1 KiB
Go
Raw Normal View History

// Copyright 2019 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package procfs
import (
"bufio"
"bytes"
"fmt"
"io"
"strconv"
"strings"
"github.com/prometheus/procfs/internal/util"
)
// Meminfo represents memory statistics.
type Meminfo struct {
// Total usable ram (i.e. physical ram minus a few reserved
// bits and the kernel binary code)
2021-02-01 17:39:00 +00:00
MemTotal *uint64
// The sum of LowFree+HighFree
2021-02-01 17:39:00 +00:00
MemFree *uint64
// An estimate of how much memory is available for starting
// new applications, without swapping. Calculated from
// MemFree, SReclaimable, the size of the file LRU lists, and
// the low watermarks in each zone. The estimate takes into
// account that the system needs some page cache to function
// well, and that not all reclaimable slab will be
// reclaimable, due to items being in use. The impact of those
// factors will vary from system to system.
2021-02-01 17:39:00 +00:00
MemAvailable *uint64
// Relatively temporary storage for raw disk blocks shouldn't
// get tremendously large (20MB or so)
2021-02-01 17:39:00 +00:00
Buffers *uint64
Cached *uint64
// Memory that once was swapped out, is swapped back in but
// still also is in the swapfile (if memory is needed it
// doesn't need to be swapped out AGAIN because it is already
// in the swapfile. This saves I/O)
2021-02-01 17:39:00 +00:00
SwapCached *uint64
// Memory that has been used more recently and usually not
// reclaimed unless absolutely necessary.
2021-02-01 17:39:00 +00:00
Active *uint64
// Memory which has been less recently used. It is more
// eligible to be reclaimed for other purposes
2021-02-01 17:39:00 +00:00
Inactive *uint64
ActiveAnon *uint64
InactiveAnon *uint64
ActiveFile *uint64
InactiveFile *uint64
Unevictable *uint64
Mlocked *uint64
// total amount of swap space available
2021-02-01 17:39:00 +00:00
SwapTotal *uint64
// Memory which has been evicted from RAM, and is temporarily
// on the disk
2021-02-01 17:39:00 +00:00
SwapFree *uint64
// Memory which is waiting to get written back to the disk
2021-02-01 17:39:00 +00:00
Dirty *uint64
// Memory which is actively being written back to the disk
2021-02-01 17:39:00 +00:00
Writeback *uint64
// Non-file backed pages mapped into userspace page tables
2021-02-01 17:39:00 +00:00
AnonPages *uint64
// files which have been mapped, such as libraries
2021-02-01 17:39:00 +00:00
Mapped *uint64
Shmem *uint64
// in-kernel data structures cache
2021-02-01 17:39:00 +00:00
Slab *uint64
// Part of Slab, that might be reclaimed, such as caches
2021-02-01 17:39:00 +00:00
SReclaimable *uint64
// Part of Slab, that cannot be reclaimed on memory pressure
2021-02-01 17:39:00 +00:00
SUnreclaim *uint64
KernelStack *uint64
// amount of memory dedicated to the lowest level of page
// tables.
2021-02-01 17:39:00 +00:00
PageTables *uint64
// NFS pages sent to the server, but not yet committed to
// stable storage
2021-02-01 17:39:00 +00:00
NFSUnstable *uint64
// Memory used for block device "bounce buffers"
2021-02-01 17:39:00 +00:00
Bounce *uint64
// Memory used by FUSE for temporary writeback buffers
2021-02-01 17:39:00 +00:00
WritebackTmp *uint64
// Based on the overcommit ratio ('vm.overcommit_ratio'),
// this is the total amount of memory currently available to
// be allocated on the system. This limit is only adhered to
// if strict overcommit accounting is enabled (mode 2 in
// 'vm.overcommit_memory').
// The CommitLimit is calculated with the following formula:
// CommitLimit = ([total RAM pages] - [total huge TLB pages]) *
// overcommit_ratio / 100 + [total swap pages]
// For example, on a system with 1G of physical RAM and 7G
// of swap with a `vm.overcommit_ratio` of 30 it would
// yield a CommitLimit of 7.3G.
// For more details, see the memory overcommit documentation
// in vm/overcommit-accounting.
2021-02-01 17:39:00 +00:00
CommitLimit *uint64
// The amount of memory presently allocated on the system.
// The committed memory is a sum of all of the memory which
// has been allocated by processes, even if it has not been
// "used" by them as of yet. A process which malloc()'s 1G
// of memory, but only touches 300M of it will show up as
// using 1G. This 1G is memory which has been "committed" to
// by the VM and can be used at any time by the allocating
// application. With strict overcommit enabled on the system
// (mode 2 in 'vm.overcommit_memory'),allocations which would
// exceed the CommitLimit (detailed above) will not be permitted.
// This is useful if one needs to guarantee that processes will
// not fail due to lack of memory once that memory has been
// successfully allocated.
2021-02-01 17:39:00 +00:00
CommittedAS *uint64
// total size of vmalloc memory area
2021-02-01 17:39:00 +00:00
VmallocTotal *uint64
// amount of vmalloc area which is used
2021-02-01 17:39:00 +00:00
VmallocUsed *uint64
// largest contiguous block of vmalloc area which is free
2021-02-01 17:39:00 +00:00
VmallocChunk *uint64
HardwareCorrupted *uint64
AnonHugePages *uint64
ShmemHugePages *uint64
ShmemPmdMapped *uint64
CmaTotal *uint64
CmaFree *uint64
HugePagesTotal *uint64
HugePagesFree *uint64
HugePagesRsvd *uint64
HugePagesSurp *uint64
Hugepagesize *uint64
DirectMap4k *uint64
DirectMap2M *uint64
DirectMap1G *uint64
}
// Meminfo returns an information about current kernel/system memory statistics.
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
func (fs FS) Meminfo() (Meminfo, error) {
b, err := util.ReadFileNoStat(fs.proc.Path("meminfo"))
if err != nil {
return Meminfo{}, err
}
m, err := parseMemInfo(bytes.NewReader(b))
if err != nil {
2023-07-07 07:04:32 +00:00
return Meminfo{}, fmt.Errorf("%s: %w", ErrFileParse, err)
}
return *m, nil
}
func parseMemInfo(r io.Reader) (*Meminfo, error) {
var m Meminfo
s := bufio.NewScanner(r)
for s.Scan() {
// Each line has at least a name and value; we ignore the unit.
fields := strings.Fields(s.Text())
if len(fields) < 2 {
2023-07-07 07:04:32 +00:00
return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, s.Text())
}
v, err := strconv.ParseUint(fields[1], 0, 64)
if err != nil {
return nil, err
}
switch fields[0] {
case "MemTotal:":
2021-02-01 17:39:00 +00:00
m.MemTotal = &v
case "MemFree:":
2021-02-01 17:39:00 +00:00
m.MemFree = &v
case "MemAvailable:":
2021-02-01 17:39:00 +00:00
m.MemAvailable = &v
case "Buffers:":
2021-02-01 17:39:00 +00:00
m.Buffers = &v
case "Cached:":
2021-02-01 17:39:00 +00:00
m.Cached = &v
case "SwapCached:":
2021-02-01 17:39:00 +00:00
m.SwapCached = &v
case "Active:":
2021-02-01 17:39:00 +00:00
m.Active = &v
case "Inactive:":
2021-02-01 17:39:00 +00:00
m.Inactive = &v
case "Active(anon):":
2021-02-01 17:39:00 +00:00
m.ActiveAnon = &v
case "Inactive(anon):":
2021-02-01 17:39:00 +00:00
m.InactiveAnon = &v
case "Active(file):":
2021-02-01 17:39:00 +00:00
m.ActiveFile = &v
case "Inactive(file):":
2021-02-01 17:39:00 +00:00
m.InactiveFile = &v
case "Unevictable:":
2021-02-01 17:39:00 +00:00
m.Unevictable = &v
case "Mlocked:":
2021-02-01 17:39:00 +00:00
m.Mlocked = &v
case "SwapTotal:":
2021-02-01 17:39:00 +00:00
m.SwapTotal = &v
case "SwapFree:":
2021-02-01 17:39:00 +00:00
m.SwapFree = &v
case "Dirty:":
2021-02-01 17:39:00 +00:00
m.Dirty = &v
case "Writeback:":
2021-02-01 17:39:00 +00:00
m.Writeback = &v
case "AnonPages:":
2021-02-01 17:39:00 +00:00
m.AnonPages = &v
case "Mapped:":
2021-02-01 17:39:00 +00:00
m.Mapped = &v
case "Shmem:":
2021-02-01 17:39:00 +00:00
m.Shmem = &v
case "Slab:":
2021-02-01 17:39:00 +00:00
m.Slab = &v
case "SReclaimable:":
2021-02-01 17:39:00 +00:00
m.SReclaimable = &v
case "SUnreclaim:":
2021-02-01 17:39:00 +00:00
m.SUnreclaim = &v
case "KernelStack:":
2021-02-01 17:39:00 +00:00
m.KernelStack = &v
case "PageTables:":
2021-02-01 17:39:00 +00:00
m.PageTables = &v
case "NFS_Unstable:":
2021-02-01 17:39:00 +00:00
m.NFSUnstable = &v
case "Bounce:":
2021-02-01 17:39:00 +00:00
m.Bounce = &v
case "WritebackTmp:":
2021-02-01 17:39:00 +00:00
m.WritebackTmp = &v
case "CommitLimit:":
2021-02-01 17:39:00 +00:00
m.CommitLimit = &v
case "Committed_AS:":
2021-02-01 17:39:00 +00:00
m.CommittedAS = &v
case "VmallocTotal:":
2021-02-01 17:39:00 +00:00
m.VmallocTotal = &v
case "VmallocUsed:":
2021-02-01 17:39:00 +00:00
m.VmallocUsed = &v
case "VmallocChunk:":
2021-02-01 17:39:00 +00:00
m.VmallocChunk = &v
case "HardwareCorrupted:":
2021-02-01 17:39:00 +00:00
m.HardwareCorrupted = &v
case "AnonHugePages:":
2021-02-01 17:39:00 +00:00
m.AnonHugePages = &v
case "ShmemHugePages:":
2021-02-01 17:39:00 +00:00
m.ShmemHugePages = &v
case "ShmemPmdMapped:":
2021-02-01 17:39:00 +00:00
m.ShmemPmdMapped = &v
case "CmaTotal:":
2021-02-01 17:39:00 +00:00
m.CmaTotal = &v
case "CmaFree:":
2021-02-01 17:39:00 +00:00
m.CmaFree = &v
case "HugePages_Total:":
2021-02-01 17:39:00 +00:00
m.HugePagesTotal = &v
case "HugePages_Free:":
2021-02-01 17:39:00 +00:00
m.HugePagesFree = &v
case "HugePages_Rsvd:":
2021-02-01 17:39:00 +00:00
m.HugePagesRsvd = &v
case "HugePages_Surp:":
2021-02-01 17:39:00 +00:00
m.HugePagesSurp = &v
case "Hugepagesize:":
2021-02-01 17:39:00 +00:00
m.Hugepagesize = &v
case "DirectMap4k:":
2021-02-01 17:39:00 +00:00
m.DirectMap4k = &v
case "DirectMap2M:":
2021-02-01 17:39:00 +00:00
m.DirectMap2M = &v
case "DirectMap1G:":
2021-02-01 17:39:00 +00:00
m.DirectMap1G = &v
}
}
return &m, nil
}