cubefs
196 строк · 6.2 Кб
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//go:build !windows
15// +build !windows
16
17package procfs18
19import (20"bytes"21"fmt"22"os"23"regexp"24"strings"25
26"github.com/prometheus/procfs/internal/util"27)
28
29// Zoneinfo holds info parsed from /proc/zoneinfo.
30type Zoneinfo struct {31Node string32Zone string33NrFreePages *int6434Min *int6435Low *int6436High *int6437Scanned *int6438Spanned *int6439Present *int6440Managed *int6441NrActiveAnon *int6442NrInactiveAnon *int6443NrIsolatedAnon *int6444NrAnonPages *int6445NrAnonTransparentHugepages *int6446NrActiveFile *int6447NrInactiveFile *int6448NrIsolatedFile *int6449NrFilePages *int6450NrSlabReclaimable *int6451NrSlabUnreclaimable *int6452NrMlockStack *int6453NrKernelStack *int6454NrMapped *int6455NrDirty *int6456NrWriteback *int6457NrUnevictable *int6458NrShmem *int6459NrDirtied *int6460NrWritten *int6461NumaHit *int6462NumaMiss *int6463NumaForeign *int6464NumaInterleave *int6465NumaLocal *int6466NumaOther *int6467Protection []*int6468}
69
70var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`)71
72// Zoneinfo parses an zoneinfo-file (/proc/zoneinfo) and returns a slice of
73// structs containing the relevant info. More information available here:
74// https://www.kernel.org/doc/Documentation/sysctl/vm.txt
75func (fs FS) Zoneinfo() ([]Zoneinfo, error) {76data, err := os.ReadFile(fs.proc.Path("zoneinfo"))77if err != nil {78return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)79}80zoneinfo, err := parseZoneinfo(data)81if err != nil {82return nil, fmt.Errorf("error parsing zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)83}84return zoneinfo, nil85}
86
87func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) {88
89zoneinfo := []Zoneinfo{}90
91zoneinfoBlocks := bytes.Split(zoneinfoData, []byte("\nNode"))92for _, block := range zoneinfoBlocks {93var zoneinfoElement Zoneinfo94lines := strings.Split(string(block), "\n")95for _, line := range lines {96
97if nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil {98zoneinfoElement.Node = nodeZone[1]99zoneinfoElement.Zone = nodeZone[2]100continue101}102if strings.HasPrefix(strings.TrimSpace(line), "per-node stats") {103continue104}105parts := strings.Fields(strings.TrimSpace(line))106if len(parts) < 2 {107continue108}109vp := util.NewValueParser(parts[1])110switch parts[0] {111case "nr_free_pages":112zoneinfoElement.NrFreePages = vp.PInt64()113case "min":114zoneinfoElement.Min = vp.PInt64()115case "low":116zoneinfoElement.Low = vp.PInt64()117case "high":118zoneinfoElement.High = vp.PInt64()119case "scanned":120zoneinfoElement.Scanned = vp.PInt64()121case "spanned":122zoneinfoElement.Spanned = vp.PInt64()123case "present":124zoneinfoElement.Present = vp.PInt64()125case "managed":126zoneinfoElement.Managed = vp.PInt64()127case "nr_active_anon":128zoneinfoElement.NrActiveAnon = vp.PInt64()129case "nr_inactive_anon":130zoneinfoElement.NrInactiveAnon = vp.PInt64()131case "nr_isolated_anon":132zoneinfoElement.NrIsolatedAnon = vp.PInt64()133case "nr_anon_pages":134zoneinfoElement.NrAnonPages = vp.PInt64()135case "nr_anon_transparent_hugepages":136zoneinfoElement.NrAnonTransparentHugepages = vp.PInt64()137case "nr_active_file":138zoneinfoElement.NrActiveFile = vp.PInt64()139case "nr_inactive_file":140zoneinfoElement.NrInactiveFile = vp.PInt64()141case "nr_isolated_file":142zoneinfoElement.NrIsolatedFile = vp.PInt64()143case "nr_file_pages":144zoneinfoElement.NrFilePages = vp.PInt64()145case "nr_slab_reclaimable":146zoneinfoElement.NrSlabReclaimable = vp.PInt64()147case "nr_slab_unreclaimable":148zoneinfoElement.NrSlabUnreclaimable = vp.PInt64()149case "nr_mlock_stack":150zoneinfoElement.NrMlockStack = vp.PInt64()151case "nr_kernel_stack":152zoneinfoElement.NrKernelStack = vp.PInt64()153case "nr_mapped":154zoneinfoElement.NrMapped = vp.PInt64()155case "nr_dirty":156zoneinfoElement.NrDirty = vp.PInt64()157case "nr_writeback":158zoneinfoElement.NrWriteback = vp.PInt64()159case "nr_unevictable":160zoneinfoElement.NrUnevictable = vp.PInt64()161case "nr_shmem":162zoneinfoElement.NrShmem = vp.PInt64()163case "nr_dirtied":164zoneinfoElement.NrDirtied = vp.PInt64()165case "nr_written":166zoneinfoElement.NrWritten = vp.PInt64()167case "numa_hit":168zoneinfoElement.NumaHit = vp.PInt64()169case "numa_miss":170zoneinfoElement.NumaMiss = vp.PInt64()171case "numa_foreign":172zoneinfoElement.NumaForeign = vp.PInt64()173case "numa_interleave":174zoneinfoElement.NumaInterleave = vp.PInt64()175case "numa_local":176zoneinfoElement.NumaLocal = vp.PInt64()177case "numa_other":178zoneinfoElement.NumaOther = vp.PInt64()179case "protection:":180protectionParts := strings.Split(line, ":")181protectionValues := strings.Replace(protectionParts[1], "(", "", 1)182protectionValues = strings.Replace(protectionValues, ")", "", 1)183protectionValues = strings.TrimSpace(protectionValues)184protectionStringMap := strings.Split(protectionValues, ", ")185val, err := util.ParsePInt64s(protectionStringMap)186if err == nil {187zoneinfoElement.Protection = val188}189}190
191}192
193zoneinfo = append(zoneinfo, zoneinfoElement)194}195return zoneinfo, nil196}
197