Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
8.0 KiB
277 lines
8.0 KiB
// 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) |
|
MemTotal uint64 |
|
// The sum of LowFree+HighFree |
|
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. |
|
MemAvailable uint64 |
|
// Relatively temporary storage for raw disk blocks shouldn't |
|
// get tremendously large (20MB or so) |
|
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) |
|
SwapCached uint64 |
|
// Memory that has been used more recently and usually not |
|
// reclaimed unless absolutely necessary. |
|
Active uint64 |
|
// Memory which has been less recently used. It is more |
|
// eligible to be reclaimed for other purposes |
|
Inactive uint64 |
|
ActiveAnon uint64 |
|
InactiveAnon uint64 |
|
ActiveFile uint64 |
|
InactiveFile uint64 |
|
Unevictable uint64 |
|
Mlocked uint64 |
|
// total amount of swap space available |
|
SwapTotal uint64 |
|
// Memory which has been evicted from RAM, and is temporarily |
|
// on the disk |
|
SwapFree uint64 |
|
// Memory which is waiting to get written back to the disk |
|
Dirty uint64 |
|
// Memory which is actively being written back to the disk |
|
Writeback uint64 |
|
// Non-file backed pages mapped into userspace page tables |
|
AnonPages uint64 |
|
// files which have been mapped, such as libraries |
|
Mapped uint64 |
|
Shmem uint64 |
|
// in-kernel data structures cache |
|
Slab uint64 |
|
// Part of Slab, that might be reclaimed, such as caches |
|
SReclaimable uint64 |
|
// Part of Slab, that cannot be reclaimed on memory pressure |
|
SUnreclaim uint64 |
|
KernelStack uint64 |
|
// amount of memory dedicated to the lowest level of page |
|
// tables. |
|
PageTables uint64 |
|
// NFS pages sent to the server, but not yet committed to |
|
// stable storage |
|
NFSUnstable uint64 |
|
// Memory used for block device "bounce buffers" |
|
Bounce uint64 |
|
// Memory used by FUSE for temporary writeback buffers |
|
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. |
|
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. |
|
CommittedAS uint64 |
|
// total size of vmalloc memory area |
|
VmallocTotal uint64 |
|
// amount of vmalloc area which is used |
|
VmallocUsed uint64 |
|
// largest contiguous block of vmalloc area which is free |
|
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 { |
|
return Meminfo{}, fmt.Errorf("failed to parse meminfo: %v", 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 { |
|
return nil, fmt.Errorf("malformed meminfo line: %q", s.Text()) |
|
} |
|
|
|
v, err := strconv.ParseUint(fields[1], 0, 64) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
switch fields[0] { |
|
case "MemTotal:": |
|
m.MemTotal = v |
|
case "MemFree:": |
|
m.MemFree = v |
|
case "MemAvailable:": |
|
m.MemAvailable = v |
|
case "Buffers:": |
|
m.Buffers = v |
|
case "Cached:": |
|
m.Cached = v |
|
case "SwapCached:": |
|
m.SwapCached = v |
|
case "Active:": |
|
m.Active = v |
|
case "Inactive:": |
|
m.Inactive = v |
|
case "Active(anon):": |
|
m.ActiveAnon = v |
|
case "Inactive(anon):": |
|
m.InactiveAnon = v |
|
case "Active(file):": |
|
m.ActiveFile = v |
|
case "Inactive(file):": |
|
m.InactiveFile = v |
|
case "Unevictable:": |
|
m.Unevictable = v |
|
case "Mlocked:": |
|
m.Mlocked = v |
|
case "SwapTotal:": |
|
m.SwapTotal = v |
|
case "SwapFree:": |
|
m.SwapFree = v |
|
case "Dirty:": |
|
m.Dirty = v |
|
case "Writeback:": |
|
m.Writeback = v |
|
case "AnonPages:": |
|
m.AnonPages = v |
|
case "Mapped:": |
|
m.Mapped = v |
|
case "Shmem:": |
|
m.Shmem = v |
|
case "Slab:": |
|
m.Slab = v |
|
case "SReclaimable:": |
|
m.SReclaimable = v |
|
case "SUnreclaim:": |
|
m.SUnreclaim = v |
|
case "KernelStack:": |
|
m.KernelStack = v |
|
case "PageTables:": |
|
m.PageTables = v |
|
case "NFS_Unstable:": |
|
m.NFSUnstable = v |
|
case "Bounce:": |
|
m.Bounce = v |
|
case "WritebackTmp:": |
|
m.WritebackTmp = v |
|
case "CommitLimit:": |
|
m.CommitLimit = v |
|
case "Committed_AS:": |
|
m.CommittedAS = v |
|
case "VmallocTotal:": |
|
m.VmallocTotal = v |
|
case "VmallocUsed:": |
|
m.VmallocUsed = v |
|
case "VmallocChunk:": |
|
m.VmallocChunk = v |
|
case "HardwareCorrupted:": |
|
m.HardwareCorrupted = v |
|
case "AnonHugePages:": |
|
m.AnonHugePages = v |
|
case "ShmemHugePages:": |
|
m.ShmemHugePages = v |
|
case "ShmemPmdMapped:": |
|
m.ShmemPmdMapped = v |
|
case "CmaTotal:": |
|
m.CmaTotal = v |
|
case "CmaFree:": |
|
m.CmaFree = v |
|
case "HugePages_Total:": |
|
m.HugePagesTotal = v |
|
case "HugePages_Free:": |
|
m.HugePagesFree = v |
|
case "HugePages_Rsvd:": |
|
m.HugePagesRsvd = v |
|
case "HugePages_Surp:": |
|
m.HugePagesSurp = v |
|
case "Hugepagesize:": |
|
m.Hugepagesize = v |
|
case "DirectMap4k:": |
|
m.DirectMap4k = v |
|
case "DirectMap2M:": |
|
m.DirectMap2M = v |
|
case "DirectMap1G:": |
|
m.DirectMap1G = v |
|
} |
|
} |
|
|
|
return &m, nil |
|
}
|
|
|