package procfs
import (
"bytes"
"fmt"
"os"
"regexp"
"strings"
"github.com/prometheus/procfs/internal/util"
)
type Zoneinfo struct {
Node string
Zone string
NrFreePages *int64
Min *int64
Low *int64
High *int64
Scanned *int64
Spanned *int64
Present *int64
Managed *int64
NrActiveAnon *int64
NrInactiveAnon *int64
NrIsolatedAnon *int64
NrAnonPages *int64
NrAnonTransparentHugepages *int64
NrActiveFile *int64
NrInactiveFile *int64
NrIsolatedFile *int64
NrFilePages *int64
NrSlabReclaimable *int64
NrSlabUnreclaimable *int64
NrMlockStack *int64
NrKernelStack *int64
NrMapped *int64
NrDirty *int64
NrWriteback *int64
NrUnevictable *int64
NrShmem *int64
NrDirtied *int64
NrWritten *int64
NumaHit *int64
NumaMiss *int64
NumaForeign *int64
NumaInterleave *int64
NumaLocal *int64
NumaOther *int64
Protection []*int64
}
var nodeZoneRE = regexp .MustCompile (`(\d+), zone\s+(\w+)` )
func (fs FS ) Zoneinfo () ([]Zoneinfo , error ) {
data , err := os .ReadFile (fs .proc .Path ("zoneinfo" ))
if err != nil {
return nil , fmt .Errorf ("%w: error reading zoneinfo %q: %w" , ErrFileRead , fs .proc .Path ("zoneinfo" ), err )
}
zoneinfo , err := parseZoneinfo (data )
if err != nil {
return nil , fmt .Errorf ("%w: error parsing zoneinfo %q: %w" , ErrFileParse , fs .proc .Path ("zoneinfo" ), err )
}
return zoneinfo , nil
}
func parseZoneinfo(zoneinfoData []byte ) ([]Zoneinfo , error ) {
zoneinfo := []Zoneinfo {}
zoneinfoBlocks := bytes .Split (zoneinfoData , []byte ("\nNode" ))
for _ , block := range zoneinfoBlocks {
var zoneinfoElement Zoneinfo
lines := strings .Split (string (block ), "\n" )
for _ , line := range lines {
if nodeZone := nodeZoneRE .FindStringSubmatch (line ); nodeZone != nil {
zoneinfoElement .Node = nodeZone [1 ]
zoneinfoElement .Zone = nodeZone [2 ]
continue
}
if strings .HasPrefix (strings .TrimSpace (line ), "per-node stats" ) {
continue
}
parts := strings .Fields (strings .TrimSpace (line ))
if len (parts ) < 2 {
continue
}
vp := util .NewValueParser (parts [1 ])
switch parts [0 ] {
case "nr_free_pages" :
zoneinfoElement .NrFreePages = vp .PInt64 ()
case "min" :
zoneinfoElement .Min = vp .PInt64 ()
case "low" :
zoneinfoElement .Low = vp .PInt64 ()
case "high" :
zoneinfoElement .High = vp .PInt64 ()
case "scanned" :
zoneinfoElement .Scanned = vp .PInt64 ()
case "spanned" :
zoneinfoElement .Spanned = vp .PInt64 ()
case "present" :
zoneinfoElement .Present = vp .PInt64 ()
case "managed" :
zoneinfoElement .Managed = vp .PInt64 ()
case "nr_active_anon" :
zoneinfoElement .NrActiveAnon = vp .PInt64 ()
case "nr_inactive_anon" :
zoneinfoElement .NrInactiveAnon = vp .PInt64 ()
case "nr_isolated_anon" :
zoneinfoElement .NrIsolatedAnon = vp .PInt64 ()
case "nr_anon_pages" :
zoneinfoElement .NrAnonPages = vp .PInt64 ()
case "nr_anon_transparent_hugepages" :
zoneinfoElement .NrAnonTransparentHugepages = vp .PInt64 ()
case "nr_active_file" :
zoneinfoElement .NrActiveFile = vp .PInt64 ()
case "nr_inactive_file" :
zoneinfoElement .NrInactiveFile = vp .PInt64 ()
case "nr_isolated_file" :
zoneinfoElement .NrIsolatedFile = vp .PInt64 ()
case "nr_file_pages" :
zoneinfoElement .NrFilePages = vp .PInt64 ()
case "nr_slab_reclaimable" :
zoneinfoElement .NrSlabReclaimable = vp .PInt64 ()
case "nr_slab_unreclaimable" :
zoneinfoElement .NrSlabUnreclaimable = vp .PInt64 ()
case "nr_mlock_stack" :
zoneinfoElement .NrMlockStack = vp .PInt64 ()
case "nr_kernel_stack" :
zoneinfoElement .NrKernelStack = vp .PInt64 ()
case "nr_mapped" :
zoneinfoElement .NrMapped = vp .PInt64 ()
case "nr_dirty" :
zoneinfoElement .NrDirty = vp .PInt64 ()
case "nr_writeback" :
zoneinfoElement .NrWriteback = vp .PInt64 ()
case "nr_unevictable" :
zoneinfoElement .NrUnevictable = vp .PInt64 ()
case "nr_shmem" :
zoneinfoElement .NrShmem = vp .PInt64 ()
case "nr_dirtied" :
zoneinfoElement .NrDirtied = vp .PInt64 ()
case "nr_written" :
zoneinfoElement .NrWritten = vp .PInt64 ()
case "numa_hit" :
zoneinfoElement .NumaHit = vp .PInt64 ()
case "numa_miss" :
zoneinfoElement .NumaMiss = vp .PInt64 ()
case "numa_foreign" :
zoneinfoElement .NumaForeign = vp .PInt64 ()
case "numa_interleave" :
zoneinfoElement .NumaInterleave = vp .PInt64 ()
case "numa_local" :
zoneinfoElement .NumaLocal = vp .PInt64 ()
case "numa_other" :
zoneinfoElement .NumaOther = vp .PInt64 ()
case "protection:" :
protectionParts := strings .Split (line , ":" )
protectionValues := strings .Replace (protectionParts [1 ], "(" , "" , 1 )
protectionValues = strings .Replace (protectionValues , ")" , "" , 1 )
protectionValues = strings .TrimSpace (protectionValues )
protectionStringMap := strings .Split (protectionValues , ", " )
val , err := util .ParsePInt64s (protectionStringMap )
if err == nil {
zoneinfoElement .Protection = val
}
}
}
zoneinfo = append (zoneinfo , zoneinfoElement )
}
return zoneinfo , nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .