From 38127272af56fc75d2910e97a4b93f7e21be8abe Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Thu, 8 Aug 2019 09:05:41 -0500 Subject: [PATCH 01/13] Add vmstat interface --- README.md | 1 + providers/linux/host_linux.go | 11 ++ providers/linux/host_linux_test.go | 17 +++ providers/linux/memory_linux.go | 28 ----- providers/linux/util.go | 25 ++++ providers/linux/vmstat.go | 46 ++++++++ providers/linux/vmstat_test.go | 155 ++++++++++++++++++++++++ types/host.go | 183 +++++++++++++++++++++++++++++ 8 files changed, 438 insertions(+), 28 deletions(-) create mode 100644 providers/linux/vmstat.go create mode 100644 providers/linux/vmstat_test.go diff --git a/README.md b/README.md index 3a657a4b..958f11c2 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ that are implemented. | `Info()` | x | x | x | | `Memory()` | x | x | x | | `CPUTimer` | x | x | x | +| `VMStat` | | x | | | `Process` Features | Darwin | Linux | Windows | |------------------------|--------|-------|---------| diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 9b09ddff..48afb64f 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -71,6 +71,17 @@ func (h *host) Memory() (*types.HostMemoryInfo, error) { return parseMemInfo(content) } +// VMStat reports data from /proc/vmstat on linux +func (h *host) VMStat() (*types.VMStatInfo, error) { + content, err := ioutil.ReadFile(h.procFS.path("vmstat")) + if err != nil { + return nil, err + } + + return parseVMStat(content) + +} + func (h *host) CPUTime() (types.CPUTimes, error) { stat, err := h.procFS.NewStat() if err != nil { diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index 98ad62c3..4edcbfc6 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -53,3 +53,20 @@ func TestHostMemoryInfo(t *testing.T) { assert.NotContains(t, m.Metrics, "MemTotal") assert.Contains(t, m.Metrics, "Slab") } + +func TestHostVMStat(t *testing.T) { + host, err := newLinuxSystem("testdata/ubuntu1710").Host() + if err != nil { + t.Fatal(err) + } + s, err := host.VMStat() + if err != nil { + t.Fatal(err) + } + + data, err := json.MarshalIndent(info, "", " ") + if err != nil { + t.Fatal(err) + } + t.Log(string(data)) +} diff --git a/providers/linux/memory_linux.go b/providers/linux/memory_linux.go index 30357430..758caaba 100644 --- a/providers/linux/memory_linux.go +++ b/providers/linux/memory_linux.go @@ -18,9 +18,6 @@ package linux import ( - "bytes" - "strconv" - "github.com/pkg/errors" "github.com/elastic/go-sysinfo/types" @@ -73,28 +70,3 @@ func parseMemInfo(content []byte) (*types.HostMemoryInfo, error) { return memInfo, nil } - -func parseBytesOrNumber(data []byte) (uint64, error) { - parts := bytes.Fields(data) - - if len(parts) == 0 { - return 0, errors.New("empty value") - } - - num, err := strconv.ParseUint(string(parts[0]), 10, 64) - if err != nil { - return 0, errors.Wrap(err, "failed to parse value") - } - - var multiplier uint64 = 1 - if len(parts) >= 2 { - switch string(parts[1]) { - case "kB": - multiplier = 1024 - default: - return 0, errors.Errorf("unhandled unit %v", string(parts[1])) - } - } - - return num * multiplier, nil -} diff --git a/providers/linux/util.go b/providers/linux/util.go index 066fef6a..0be3f6b0 100644 --- a/providers/linux/util.go +++ b/providers/linux/util.go @@ -84,3 +84,28 @@ func decodeBitMap(s string, lookupName func(int) string) ([]string, error) { return names, nil } + +func parseBytesOrNumber(data []byte) (uint64, error) { + parts := bytes.Fields(data) + + if len(parts) == 0 { + return 0, errors.New("empty value") + } + + num, err := strconv.ParseUint(string(parts[0]), 10, 64) + if err != nil { + return 0, errors.Wrap(err, "failed to parse value") + } + + var multiplier uint64 = 1 + if len(parts) >= 2 { + switch string(parts[1]) { + case "kB": + multiplier = 1024 + default: + return 0, errors.Errorf("unhandled unit %v", string(parts[1])) + } + } + + return num * multiplier, nil +} diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go new file mode 100644 index 00000000..7e42ac77 --- /dev/null +++ b/providers/linux/vmstat.go @@ -0,0 +1,46 @@ +package linux + +import ( + "reflect" + + "github.com/elastic/go-sysinfo/types" + "github.com/pkg/errors" +) + +// parseVMStat parses the contents of /proc/vmstat +func parseVMStat(content []byte) (*types.VMStatInfo, error) { + + vmStat := &types.VMStatInfo{} + refVal := reflect.ValueOf(vmStat).Elem() + + err := parseKeyValue(content, " ", func(key, value []byte) error { + // turn our []byte value into an int + val, err := parseBytesOrNumber(value) + if err != nil { + return errors.Wrapf(err, "failed to parse %v value of %v", string(key), string(value)) + } + + // Search The struct object to see if we have a field with a tag that matches the raw key coming off the file input + // This is the best way I've found to "search" for a a struct field based on a struct tag value. + // In this case, the /proc/vmstat keys are struct tags. + fieldToSet := refVal.FieldByNameFunc(func(name string) bool { + testField, exists := reflect.TypeOf(vmStat).Elem().FieldByName(name) + if !exists { + return false + } + if testField.Tag.Get("vmstat") == string(key) { + return true + } + return false + }) + + // This protects us from fields in /proc/vmstat that we don't have added in our struct + //This is just a way to make sure we actually found a field in the above `FieldByNameFunc` + if fieldToSet.CanSet() { + fieldToSet.SetUint(val) + } + return nil + }) + + return vmStat, err +} diff --git a/providers/linux/vmstat_test.go b/providers/linux/vmstat_test.go new file mode 100644 index 00000000..42846d9a --- /dev/null +++ b/providers/linux/vmstat_test.go @@ -0,0 +1,155 @@ +package linux + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var rawInput = ` +nr_free_pages 50545 +nr_zone_inactive_anon 66 +nr_zone_active_anon 26799 +nr_zone_inactive_file 31849 +nr_zone_active_file 94164 +nr_zone_unevictable 0 +nr_zone_write_pending 7 +nr_mlock 0 +nr_page_table_pages 1225 +nr_kernel_stack 2496 +nr_bounce 0 +nr_zspages 0 +nr_free_cma 0 +numa_hit 44470329 +numa_miss 0 +numa_foreign 0 +numa_interleave 16296 +numa_local 44470329 +numa_other 0 +nr_inactive_anon 66 +nr_active_anon 26799 +nr_inactive_file 31849 +nr_active_file 94164 +nr_unevictable 0 +nr_slab_reclaimable 31763 +nr_slab_unreclaimable 10329 +nr_isolated_anon 0 +nr_isolated_file 0 +workingset_refault 302914 +workingset_activate 108959 +workingset_nodereclaim 6422 +nr_anon_pages 26218 +nr_mapped 8641 +nr_file_pages 126182 +nr_dirty 7 +nr_writeback 0 +nr_writeback_temp 0 +nr_shmem 169 +nr_shmem_hugepages 0 +nr_shmem_pmdmapped 0 +nr_anon_transparent_hugepages 0 +nr_unstable 0 +nr_vmscan_write 35 +nr_vmscan_immediate_reclaim 9832 +nr_dirtied 7188920 +nr_written 6479005 +nr_dirty_threshold 31736 +nr_dirty_background_threshold 15848 +pgpgin 17010697 +pgpgout 27734292 +pswpin 0 +pswpout 0 +pgalloc_dma 241378 +pgalloc_dma32 45788683 +pgalloc_normal 0 +pgalloc_movable 0 +allocstall_dma 0 +allocstall_dma32 0 +allocstall_normal 5 +allocstall_movable 8 +pgskip_dma 0 +pgskip_dma32 0 +pgskip_normal 0 +pgskip_movable 0 +pgfree 46085578 +pgactivate 2475069 +pgdeactivate 636658 +pglazyfree 9426 +pgfault 46777498 +pgmajfault 19204 +pglazyfreed 0 +pgrefill 707817 +pgsteal_kswapd 3798890 +pgsteal_direct 1466 +pgscan_kswapd 3868525 +pgscan_direct 1483 +pgscan_direct_throttle 0 +zone_reclaim_failed 0 +pginodesteal 1710 +slabs_scanned 8348560 +kswapd_inodesteal 3142001 +kswapd_low_wmark_hit_quickly 541 +kswapd_high_wmark_hit_quickly 332 +pageoutrun 1492 +pgrotated 29725 +drop_pagecache 0 +drop_slab 0 +oom_kill 0 +numa_pte_updates 0 +numa_huge_pte_updates 0 +numa_hint_faults 0 +numa_hint_faults_local 0 +numa_pages_migrated 0 +pgmigrate_success 4539 +pgmigrate_fail 156 +compact_migrate_scanned 9331 +compact_free_scanned 136266 +compact_isolated 9407 +compact_stall 2 +compact_fail 0 +compact_success 2 +compact_daemon_wake 21 +compact_daemon_migrate_scanned 8311 +compact_daemon_free_scanned 107086 +htlb_buddy_alloc_success 0 +htlb_buddy_alloc_fail 0 +unevictable_pgs_culled 19 +unevictable_pgs_scanned 0 +unevictable_pgs_rescued 304 +unevictable_pgs_mlocked 304 +unevictable_pgs_munlocked 304 +unevictable_pgs_cleared 0 +unevictable_pgs_stranded 0 +thp_fault_alloc 2 +thp_fault_fallback 0 +thp_collapse_alloc 2 +thp_collapse_alloc_failed 0 +thp_file_alloc 0 +thp_file_mapped 0 +thp_split_page 0 +thp_split_page_failed 0 +thp_deferred_split_page 4 +thp_split_pmd 1 +thp_split_pud 0 +thp_zero_page_alloc 0 +thp_zero_page_alloc_failed 0 +thp_swpout 0 +thp_swpout_fallback 0 +balloon_inflate 0 +balloon_deflate 0 +balloon_migrate 0 +swap_ra 0 +swap_ra_hit 0 +` + +func TestVmStatParse(t *testing.T) { + data, err := parseVMStat([]byte(rawInput)) + if err != nil { + t.Fatal(err) + } + + // Check a few values + assert.Equal(t, uint64(8348560), data.SlabsScanned) + assert.Equal(t, uint64(0), data.SwapRa) + assert.Equal(t, uint64(108959), data.WorkingsetActivate) +} diff --git a/types/host.go b/types/host.go index 198dac1c..8166c611 100644 --- a/types/host.go +++ b/types/host.go @@ -26,6 +26,11 @@ type Host interface { Memory() (*HostMemoryInfo, error) } +// VMStat is the interface wrapper for platforms that support /proc/vmstat +type VMStat interface { + VMStat() (VMStatInfo, error) +} + // HostInfo contains basic host information type HostInfo struct { Architecture string `json:"architecture"` // Hardware architecture (e.g. x86_64, arm, ppc, mips). @@ -83,3 +88,181 @@ type HostMemoryInfo struct { VirtualFree uint64 `json:"virtual_free_bytes"` // Virtual memory that is not used. Metrics map[string]uint64 `json:"raw,omitempty"` // Other memory related metrics. } + +// VMStatInfo contains parsed info from /proc/vmstat +// This procfs file has expanded much over the years +// with different kernel versions. If we don't have a field in vmstat, +// the field in the struct will just be blank. The comments represent kernel versions. +type VMStatInfo struct { + NrFreePages uint64 `vmstat:"nr_free_pages"` // (since Linux 2.6.31) + NrAllocBatch uint64 `vmstat:"nr_alloc_batch"` // (since Linux 3.12) + NrInactiveAnon uint64 `vmstat:"nr_inactive_anon"` // (since Linux 2.6.28) + NrActiveAnon uint64 `vmstat:"nr_active_anon"` // (since Linux 2.6.28) + NrInactiveFile uint64 `vmstat:"nr_inactive_file"` // (since Linux 2.6.28) + NrActiveFile uint64 `vmstat:"nr_active_file"` // (since Linux 2.6.28) + NrUnevictable uint64 `vmstat:"nr_unevictable"` // (since Linux 2.6.28) + NrMlock uint64 `vmstat:"nr_mlock"` // (since Linux 2.6.28) + NrAnonPages uint64 `vmstat:"nr_anon_pages"` // (since Linux 2.6.18) + NrMapped uint64 `vmstat:"nr_mapped"` // (since Linux 2.6.0) + NrFilePages uint64 `vmstat:"nr_file_pages"` // (since Linux 2.6.18) + NrDirty uint64 `vmstat:"nr_dirty"` // (since Linux 2.6.0) + NrWriteback uint64 `vmstat:"nr_writeback"` // (since Linux 2.6.0) + NrSlabReclaimable uint64 `vmstat:"nr_slab_reclaimable"` // (since Linux 2.6.19) + NrSlabUnreclaimable uint64 `vmstat:"nr_slab_unreclaimable"` // (since Linux 2.6.19) + NrPageTablePages uint64 `vmstat:"nr_page_table_pages"` // (since Linux 2.6.0) + NrKernelStack uint64 `vmstat:"nr_kernel_stack"` // (since Linux 2.6.32) Amount of memory allocated to kernel stacks. + NrUnstable uint64 `vmstat:"nr_unstable"` // (since Linux 2.6.0) + NrBounce uint64 `vmstat:"nr_bounce"` // (since Linux 2.6.12) + NrVmscanWrite uint64 `vmstat:"nr_vmscan_write"` // (since Linux 2.6.19) + NrVmscanImmediateReclaim uint64 `vmstat:"nr_vmscan_immediate_reclaim"` // (since Linux 3.2) + NrWritebackTemp uint64 `vmstat:"nr_writeback_temp"` // (since Linux 2.6.26) + NrIsolatedAnon uint64 `vmstat:"nr_isolated_anon"` // (since Linux 2.6.32) + NrIsolatedFile uint64 `vmstat:"nr_isolated_file"` // (since Linux 2.6.32) + NrShmem uint64 `vmstat:"nr_shmem"` // (since Linux 2.6.32) Pages used by shmem and tmpfs(5). + NrDirtied uint64 `vmstat:"nr_dirtied"` // (since Linux 2.6.37) + NrWritten uint64 `vmstat:"nr_written"` // (since Linux 2.6.37) + NrPagesScanned uint64 `vmstat:"nr_pages_scanned"` // (since Linux 3.17) + NumaHit uint64 `vmstat:"numa_hit"` // (since Linux 2.6.18) + NumaMiss uint64 `vmstat:"numa_miss"` // (since Linux 2.6.18) + NumaForeign uint64 `vmstat:"numa_foreign"` // (since Linux 2.6.18) + NumaInterleave uint64 `vmstat:"numa_interleave"` // (since Linux 2.6.18) + NumaLocal uint64 `vmstat:"numa_local"` // (since Linux 2.6.18) + NumaOther uint64 `vmstat:"numa_other"` // (since Linux 2.6.18) + WorkingsetRefault uint64 `vmstat:"workingset_refault"` // (since Linux 3.15) + WorkingsetActivate uint64 `vmstat:"workingset_activate"` // (since Linux 3.15) + WorkingsetNodereclaim uint64 `vmstat:"workingset_nodereclaim"` // (since Linux 3.15) + NrAnonTransparentHugepages uint64 `vmstat:"nr_anon_transparent_hugepages"` // (since Linux 2.6.38) + NrFreeCma uint64 `vmstat:"nr_free_cma"` // (since Linux 3.7) Number of free CMA (Contiguous Memory Allocator) pages. + NrDirtyThreshold uint64 `vmstat:"nr_dirty_threshold"` // (since Linux 2.6.37) + NrDirtyBackgroundThreshold uint64 `vmstat:"nr_dirty_background_threshold"` // (since Linux 2.6.37) + Pgpgin uint64 `vmstat:"pgpgin"` // (since Linux 2.6.0) + Pgpgout uint64 `vmstat:"pgpgout"` // (since Linux 2.6.0) + Pswpin uint64 `vmstat:"pswpin"` // (since Linux 2.6.0) + Pswpout uint64 `vmstat:"pswpout"` // (since Linux 2.6.0) + PgallocDma uint64 `vmstat:"pgalloc_dma"` // (since Linux 2.6.5) + PgallocDma32 uint64 `vmstat:"pgalloc_dma32"` // (since Linux 2.6.16) + PgallocNormal uint64 `vmstat:"pgalloc_normal"` // (since Linux 2.6.5) + PgallocHigh uint64 `vmstat:"pgalloc_high"` // (since Linux 2.6.5) + PgallocMovable uint64 `vmstat:"pgalloc_movable"` // (since Linux 2.6.23) + Pgfree uint64 `vmstat:"pgfree"` // (since Linux 2.6.0) + Pgactivate uint64 `vmstat:"pgactivate"` // (since Linux 2.6.0) + Pgdeactivate uint64 `vmstat:"pgdeactivate"` // (since Linux 2.6.0) + Pgfault uint64 `vmstat:"pgfault"` // (since Linux 2.6.0) + Pgmajfault uint64 `vmstat:"pgmajfault"` // (since Linux 2.6.0) + PgrefillDma uint64 `vmstat:"pgrefill_dma"` // (since Linux 2.6.5) + PgrefillDma32 uint64 `vmstat:"pgrefill_dma32"` // (since Linux 2.6.16) + PgrefillNormal uint64 `vmstat:"pgrefill_normal"` // (since Linux 2.6.5) + PgrefillHigh uint64 `vmstat:"pgrefill_high"` // (since Linux 2.6.5) + PgrefillMovable uint64 `vmstat:"pgrefill_movable"` // (since Linux 2.6.23) + PgstealKswapdDma uint64 `vmstat:"pgsteal_kswapd_dma"` // (since Linux 3.4) + PgstealKswapdDma32 uint64 `vmstat:"pgsteal_kswapd_dma32"` // (since Linux 3.4) + PgstealKswapdNormal uint64 `vmstat:"pgsteal_kswapd_normal"` // (since Linux 3.4) + PgstealKswapdHigh uint64 `vmstat:"pgsteal_kswapd_high"` // (since Linux 3.4) + PgstealKswapdMovable uint64 `vmstat:"pgsteal_kswapd_movable"` // (since Linux 3.4) + PgstealDirectDma uint64 `vmstat:"pgsteal_direct_dma"` + PgstealDirectDma32 uint64 `vmstat:"pgsteal_direct_dma32"` // (since Linux 3.4) + PgstealDirectNormal uint64 `vmstat:"pgsteal_direct_normal"` // (since Linux 3.4) + PgstealDirectHigh uint64 `vmstat:"pgsteal_direct_high"` // (since Linux 3.4) + PgstealDirectMovable uint64 `vmstat:"pgsteal_direct_movable"` // (since Linux 2.6.23) + PgscanKswapdDma uint64 `vmstat:"pgscan_kswapd_dma"` + PgscanKswapdDma32 uint64 `vmstat:"pgscan_kswapd_dma32"` // (since Linux 2.6.16) + PgscanKswapdNormal uint64 `vmstat:"pgscan_kswapd_normal"` // (since Linux 2.6.5) + PgscanKswapdHigh uint64 `vmstat:"pgscan_kswapd_high"` + PgscanKswapdMovable uint64 `vmstat:"pgscan_kswapd_movable"` // (since Linux 2.6.23) + PgscanDirectDma uint64 `vmstat:"pgscan_direct_dma"` // + PgscanDirectDma32 uint64 `vmstat:"pgscan_direct_dma32"` // (since Linux 2.6.16) + PgscanDirectNormal uint64 `vmstat:"pgscan_direct_normal"` + PgscanDirectHigh uint64 `vmstat:"pgscan_direct_high"` + PgscanDirectMovable uint64 `vmstat:"pgscan_direct_movable"` // (since Linux 2.6.23) + PgscanDirectThrottle uint64 `vmstat:"pgscan_direct_throttle"` // (since Linux 3.6) + ZoneReclaimFailed uint64 `vmstat:"zone_reclaim_failed"` // (since linux 2.6.31) + Pginodesteal uint64 `vmstat:"pginodesteal"` // (since linux 2.6.0) + SlabsScanned uint64 `vmstat:"slabs_scanned"` // (since linux 2.6.5) + KswapdInodesteal uint64 `vmstat:"kswapd_inodesteal"` // (since linux 2.6.0) + KswapdLowWmarkHitQuickly uint64 `vmstat:"kswapd_low_wmark_hit_quickly"` // (since 2.6.33) + KswapdHighWmarkHitQuickly uint64 `vmstat:"kswapd_high_wmark_hit_quickly"` // (since 2.6.33) + Pageoutrun uint64 `vmstat:"pageoutrun"` // (since Linux 2.6.0) + Allocstall uint64 `vmstat:"allocstall"` // (since Linux 2.6.0) + Pgrotated uint64 `vmstat:"pgrotated"` // (since Linux 2.6.0) + DropPagecache uint64 `vmstat:"drop_pagecache"` // (since Linux 3.15) + DropSlab uint64 `vmstat:"drop_slab"` // (since Linux 3.15) + NumaPteUpdates uint64 `vmstat:"numa_pte_updates"` // (since Linux 3.8) + NumaHugePteUpdates uint64 `vmstat:"numa_huge_pte_updates"` // (since Linux 3.13) + NumaHintFaults uint64 `vmstat:"numa_hint_faults"` // (since Linux 3.8) + NumaHintFaultsLocal uint64 `vmstat:"numa_hint_faults_local"` // (since Linux 3.8) + NumaPagesMigrated uint64 `vmstat:"numa_pages_migrated"` // (since Linux 3.8) + PgmigrateSuccess uint64 `vmstat:"pgmigrate_success"` // (since Linux 3.8) + PgmigrateFail uint64 `vmstat:"pgmigrate_fail"` // (since Linux 3.8) + CompactMigrateScanned uint64 `vmstat:"compact_migrate_scanned"` // (since Linux 3.8) + CompactFreeScanned uint64 `vmstat:"compact_free_scanned"` // (since Linux 3.8) + CompactIsolated uint64 `vmstat:"compact_isolated"` // (since Linux 3.8) + CompactStall uint64 `vmstat:"compact_stall"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + CompactFail uint64 `vmstat:"compact_fail"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + CompactSuccess uint64 `vmstat:"compact_success"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + HtlbBuddyAllocSuccess uint64 `vmstat:"htlb_buddy_alloc_success"` // (since Linux 2.6.26) + HtlbBuddyAllocFail uint64 `vmstat:"htlb_buddy_alloc_fail"` // (since Linux 2.6.26) + UnevictablePgsCulled uint64 `vmstat:"unevictable_pgs_culled"` // (since Linux 2.6.28) + UnevictablePgsScanned uint64 `vmstat:"unevictable_pgs_scanned"` // (since Linux 2.6.28) + UnevictablePgsRescued uint64 `vmstat:"unevictable_pgs_rescued"` // (since Linux 2.6.28) + UnevictablePgsMlocked uint64 `vmstat:"unevictable_pgs_mlocked"` // (since Linux 2.6.28) + UnevictablePgsMunlocked uint64 `vmstat:"unevictable_pgs_munlocked"` // (since Linux 2.6.28) + UnevictablePgsCleared uint64 `vmstat:"unevictable_pgs_cleared"` // (since Linux 2.6.28) + UnevictablePgsStranded uint64 `vmstat:"unevictable_pgs_stranded"` // (since Linux 2.6.28) + ThpFaultAlloc uint64 `vmstat:"thp_fault_alloc"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpFaultFallback uint64 `vmstat:"thp_fault_fallback"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpCollapseAlloc uint64 `vmstat:"thp_collapse_alloc"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpCollapseAllocFailed uint64 `vmstat:"thp_collapse_alloc_failed"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpSplit uint64 `vmstat:"thp_split"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpZeroPageAlloc uint64 `vmstat:"thp_zero_page_alloc"` // (since Linux 3.8) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpZeroPageAllocFailed uint64 `vmstat:"thp_zero_page_alloc_failed"` // (since Linux 3.8) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + BalloonInflate uint64 `vmstat:"balloon_inflate"` // (since Linux 3.18) + BalloonDeflate uint64 `vmstat:"balloon_deflate"` // (since Linux 3.18) + BalloonMigrate uint64 `vmstat:"balloon_migrate"` // (since Linux 3.18) + NrTlbRemoteFlush uint64 `vmstat:"nr_tlb_remote_flush"` // (since Linux 3.12) + NrTlbRemoteFlushReceived uint64 `vmstat:"nr_tlb_remote_flush_received"` // (since Linux 3.12) + NrTlbLocalFlushAll uint64 `vmstat:"nr_tlb_local_flush_all"` // (since Linux 3.12) + NrTlbLocalFlushOne uint64 `vmstat:"nr_tlb_local_flush_one"` // (since Linux 3.12) + VmacacheFindCalls uint64 `vmstat:"vmacache_find_calls"` // (since Linux 3.16) + VmacacheFindHits uint64 `vmstat:"vmacache_find_hits"` // (since Linux 3.16) + VmacacheFullFlushes uint64 `vmstat:"vmacache_full_flushes"` // (since Linux 3.19) + // the following fields are not documented in `man 5 proc` as of 4.15 + NrZoneInactiveAnon uint64 `vmstat:"nr_zone_inactive_anon"` + NrZoneActiveAnon uint64 `vmstat:"nr_zone_active_anon"` + NrZoneInactiveFile uint64 `vmstat:"nr_zone_inactive_file"` + NrZoneActiveFile uint64 `vmstat:"nr_zone_active_file"` + NrZoneUnevictable uint64 `vmstat:"nr_zone_unevictable"` + NrZoneWritePending uint64 `vmstat:"nr_zone_write_pending"` + NrZspages uint64 `vmstat:"nr_zspages"` + NrShmemHugepages uint64 `vmstat:"nr_shmem_hugepages"` + NrShmemPmdmapped uint64 `vmstat:"nr_shmem_pmdmapped"` + AllocstallDma uint64 `vmstat:"allocstall_dma"` + AllocstallDma32 uint64 `vmstat:"allocstall_dma32"` + AllocstallNormal uint64 `vmstat:"allocstall_normal"` + AllocstallMovable uint64 `vmstat:"allocstall_movable"` + PgskipDma uint64 `vmstat:"pgskip_dma"` + PgskipDma32 uint64 `vmstat:"pgskip_dma32"` + PgskipNormal uint64 `vmstat:"pgskip_normal"` + PgskipMovable uint64 `vmstat:"pgskip_movable"` + Pglazyfree uint64 `vmstat:"pglazyfree"` + Pglazyfreed uint64 `vmstat:"pglazyfreed"` + Pgrefill uint64 `vmstat:"pgrefill"` + PgstealKswapd uint64 `vmstat:"pgsteal_kswapd"` + PgstealDirect uint64 `vmstat:"pgsteal_direct"` + PgscanKswapd uint64 `vmstat:"pgscan_kswapd"` + PgscanDirect uint64 `vmstat:"pgscan_direct"` + OomKill uint64 `vmstat:"oom_kill"` + CompactDaemonWake uint64 `vmstat:"compact_daemon_wake"` + CompactDaemonMigrateScanned uint64 `vmstat:"compact_daemon_migrate_scanned"` + CompactDaemonFreeScanned uint64 `vmstat:"compact_daemon_free_scanned"` + ThpFileAlloc uint64 `vmstat:"thp_file_alloc"` + ThpFileMapped uint64 `vmstat:"thp_file_mapped"` + ThpSplitPage uint64 `vmstat:"thp_split_page"` + ThpSplitPageFailed uint64 `vmstat:"thp_split_page_failed"` + ThpDeferredSplitPage uint64 `vmstat:"thp_deferred_split_page"` + ThpSplitPmd uint64 `vmstat:"thp_split_pmd"` + ThpSplitPud uint64 `vmstat:"thp_split_pud"` + ThpSwpout uint64 `vmstat:"thp_swpout"` + ThpSwpoutFallback uint64 `vmstat:"thp_swpout_fallback"` + SwapRa uint64 `vmstat:"swap_ra"` + SwapRaHit uint64 `vmstat:"swap_ra_hit"` +} From 558f0e35f3f11db595b948c6bf01b00817129e10 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Thu, 8 Aug 2019 09:19:26 -0500 Subject: [PATCH 02/13] add lic leader --- providers/linux/vmstat.go | 17 +++++++++++++++++ providers/linux/vmstat_test.go | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go index 7e42ac77..61ccddf9 100644 --- a/providers/linux/vmstat.go +++ b/providers/linux/vmstat.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 linux import ( diff --git a/providers/linux/vmstat_test.go b/providers/linux/vmstat_test.go index 42846d9a..df7a57ed 100644 --- a/providers/linux/vmstat_test.go +++ b/providers/linux/vmstat_test.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 linux import ( From 0a791da30fb36e8285f2f9862194e0aa98bd9b3f Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Thu, 8 Aug 2019 09:27:54 -0500 Subject: [PATCH 03/13] fmt code --- providers/linux/host_linux.go | 1 - providers/linux/vmstat.go | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 48afb64f..335fb0dc 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -79,7 +79,6 @@ func (h *host) VMStat() (*types.VMStatInfo, error) { } return parseVMStat(content) - } func (h *host) CPUTime() (types.CPUTimes, error) { diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go index 61ccddf9..6206f089 100644 --- a/providers/linux/vmstat.go +++ b/providers/linux/vmstat.go @@ -26,7 +26,6 @@ import ( // parseVMStat parses the contents of /proc/vmstat func parseVMStat(content []byte) (*types.VMStatInfo, error) { - vmStat := &types.VMStatInfo{} refVal := reflect.ValueOf(vmStat).Elem() @@ -52,7 +51,7 @@ func parseVMStat(content []byte) (*types.VMStatInfo, error) { }) // This protects us from fields in /proc/vmstat that we don't have added in our struct - //This is just a way to make sure we actually found a field in the above `FieldByNameFunc` + // This is just a way to make sure we actually found a field in the above `FieldByNameFunc` if fieldToSet.CanSet() { fieldToSet.SetUint(val) } From d41d6aacdfbb547e2dc9213617f38d1ac6f6e4b2 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Thu, 8 Aug 2019 09:32:31 -0500 Subject: [PATCH 04/13] fmt code, again --- system_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/system_test.go b/system_test.go index 62b4ab29..5daabb01 100644 --- a/system_test.go +++ b/system_test.go @@ -290,5 +290,4 @@ func TestProcesses(t *testing.T) { info.PID, info.Name, info.Exe, info.Args, info.PPID, info.CWD, info.StartTime) } - } From 1492d7bf38caa293b040e4a1f75df0f171f98a4c Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Thu, 8 Aug 2019 09:37:56 -0500 Subject: [PATCH 05/13] Alright, I figured out how we run goimports --- providers/linux/vmstat.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go index 6206f089..88c85302 100644 --- a/providers/linux/vmstat.go +++ b/providers/linux/vmstat.go @@ -20,8 +20,9 @@ package linux import ( "reflect" - "github.com/elastic/go-sysinfo/types" "github.com/pkg/errors" + + "github.com/elastic/go-sysinfo/types" ) // parseVMStat parses the contents of /proc/vmstat From 3a9ebec448b583c8503f6e59001e394aa23a0813 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Thu, 8 Aug 2019 10:08:55 -0500 Subject: [PATCH 06/13] fix tests --- providers/linux/host_linux_test.go | 8 +- .../linux/testdata/ubuntu1710/proc/vmstat | 133 ++++++++++++++++++ types/host.go | 2 +- 3 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 providers/linux/testdata/ubuntu1710/proc/vmstat diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index 4edcbfc6..a6be0270 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -21,9 +21,9 @@ import ( "encoding/json" "testing" - "github.com/stretchr/testify/assert" - "github.com/elastic/go-sysinfo/internal/registry" + "github.com/elastic/go-sysinfo/types" + "github.com/stretchr/testify/assert" ) var _ registry.HostProvider = linuxSystem{} @@ -59,12 +59,12 @@ func TestHostVMStat(t *testing.T) { if err != nil { t.Fatal(err) } - s, err := host.VMStat() + s, err := host.(types.VMStat).VMStat() if err != nil { t.Fatal(err) } - data, err := json.MarshalIndent(info, "", " ") + data, err := json.MarshalIndent(s, "", " ") if err != nil { t.Fatal(err) } diff --git a/providers/linux/testdata/ubuntu1710/proc/vmstat b/providers/linux/testdata/ubuntu1710/proc/vmstat new file mode 100644 index 00000000..7ff1d855 --- /dev/null +++ b/providers/linux/testdata/ubuntu1710/proc/vmstat @@ -0,0 +1,133 @@ +nr_free_pages 50545 +nr_zone_inactive_anon 66 +nr_zone_active_anon 26799 +nr_zone_inactive_file 31849 +nr_zone_active_file 94164 +nr_zone_unevictable 0 +nr_zone_write_pending 7 +nr_mlock 0 +nr_page_table_pages 1225 +nr_kernel_stack 2496 +nr_bounce 0 +nr_zspages 0 +nr_free_cma 0 +numa_hit 44470329 +numa_miss 0 +numa_foreign 0 +numa_interleave 16296 +numa_local 44470329 +numa_other 0 +nr_inactive_anon 66 +nr_active_anon 26799 +nr_inactive_file 31849 +nr_active_file 94164 +nr_unevictable 0 +nr_slab_reclaimable 31763 +nr_slab_unreclaimable 10329 +nr_isolated_anon 0 +nr_isolated_file 0 +workingset_refault 302914 +workingset_activate 108959 +workingset_nodereclaim 6422 +nr_anon_pages 26218 +nr_mapped 8641 +nr_file_pages 126182 +nr_dirty 7 +nr_writeback 0 +nr_writeback_temp 0 +nr_shmem 169 +nr_shmem_hugepages 0 +nr_shmem_pmdmapped 0 +nr_anon_transparent_hugepages 0 +nr_unstable 0 +nr_vmscan_write 35 +nr_vmscan_immediate_reclaim 9832 +nr_dirtied 7188920 +nr_written 6479005 +nr_dirty_threshold 31736 +nr_dirty_background_threshold 15848 +pgpgin 17010697 +pgpgout 27734292 +pswpin 0 +pswpout 0 +pgalloc_dma 241378 +pgalloc_dma32 45788683 +pgalloc_normal 0 +pgalloc_movable 0 +allocstall_dma 0 +allocstall_dma32 0 +allocstall_normal 5 +allocstall_movable 8 +pgskip_dma 0 +pgskip_dma32 0 +pgskip_normal 0 +pgskip_movable 0 +pgfree 46085578 +pgactivate 2475069 +pgdeactivate 636658 +pglazyfree 9426 +pgfault 46777498 +pgmajfault 19204 +pglazyfreed 0 +pgrefill 707817 +pgsteal_kswapd 3798890 +pgsteal_direct 1466 +pgscan_kswapd 3868525 +pgscan_direct 1483 +pgscan_direct_throttle 0 +zone_reclaim_failed 0 +pginodesteal 1710 +slabs_scanned 8348560 +kswapd_inodesteal 3142001 +kswapd_low_wmark_hit_quickly 541 +kswapd_high_wmark_hit_quickly 332 +pageoutrun 1492 +pgrotated 29725 +drop_pagecache 0 +drop_slab 0 +oom_kill 0 +numa_pte_updates 0 +numa_huge_pte_updates 0 +numa_hint_faults 0 +numa_hint_faults_local 0 +numa_pages_migrated 0 +pgmigrate_success 4539 +pgmigrate_fail 156 +compact_migrate_scanned 9331 +compact_free_scanned 136266 +compact_isolated 9407 +compact_stall 2 +compact_fail 0 +compact_success 2 +compact_daemon_wake 21 +compact_daemon_migrate_scanned 8311 +compact_daemon_free_scanned 107086 +htlb_buddy_alloc_success 0 +htlb_buddy_alloc_fail 0 +unevictable_pgs_culled 19 +unevictable_pgs_scanned 0 +unevictable_pgs_rescued 304 +unevictable_pgs_mlocked 304 +unevictable_pgs_munlocked 304 +unevictable_pgs_cleared 0 +unevictable_pgs_stranded 0 +thp_fault_alloc 2 +thp_fault_fallback 0 +thp_collapse_alloc 2 +thp_collapse_alloc_failed 0 +thp_file_alloc 0 +thp_file_mapped 0 +thp_split_page 0 +thp_split_page_failed 0 +thp_deferred_split_page 4 +thp_split_pmd 1 +thp_split_pud 0 +thp_zero_page_alloc 0 +thp_zero_page_alloc_failed 0 +thp_swpout 0 +thp_swpout_fallback 0 +balloon_inflate 0 +balloon_deflate 0 +balloon_migrate 0 +swap_ra 0 +swap_ra_hit 0 \ No newline at end of file diff --git a/types/host.go b/types/host.go index 8166c611..92b2a6ff 100644 --- a/types/host.go +++ b/types/host.go @@ -28,7 +28,7 @@ type Host interface { // VMStat is the interface wrapper for platforms that support /proc/vmstat type VMStat interface { - VMStat() (VMStatInfo, error) + VMStat() (*VMStatInfo, error) } // HostInfo contains basic host information From 18f2cdfbbf84a5c5a123538f1a2ce3360ad80e87 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Thu, 8 Aug 2019 10:12:23 -0500 Subject: [PATCH 07/13] goimports again --- providers/linux/host_linux_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index a6be0270..17bb4ade 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -21,9 +21,10 @@ import ( "encoding/json" "testing" + "github.com/stretchr/testify/assert" + "github.com/elastic/go-sysinfo/internal/registry" "github.com/elastic/go-sysinfo/types" - "github.com/stretchr/testify/assert" ) var _ registry.HostProvider = linuxSystem{} From a48bf8f10c33e738d0f2229ca646f29bb14e8d76 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Fri, 16 Aug 2019 10:26:07 -0500 Subject: [PATCH 08/13] change vmstat struct filling algo, use json struct tags --- providers/linux/vmstat.go | 34 ++-- providers/linux/vmstat_test.go | 1 - types/host.go | 340 ++++++++++++++++----------------- 3 files changed, 186 insertions(+), 189 deletions(-) diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go index 88c85302..2f0898ea 100644 --- a/providers/linux/vmstat.go +++ b/providers/linux/vmstat.go @@ -29,6 +29,14 @@ import ( func parseVMStat(content []byte) (*types.VMStatInfo, error) { vmStat := &types.VMStatInfo{} refVal := reflect.ValueOf(vmStat).Elem() + tagMap := make(map[string]*reflect.Value) + + //iterate over the struct and make a map of tags->values + for index := 0; index < refVal.NumField(); index++ { + tag := refVal.Type().Field(index).Tag.Get("json") + val := refVal.Field(index) + tagMap[tag] = &val + } err := parseKeyValue(content, " ", func(key, value []byte) error { // turn our []byte value into an int @@ -37,26 +45,16 @@ func parseVMStat(content []byte) (*types.VMStatInfo, error) { return errors.Wrapf(err, "failed to parse %v value of %v", string(key), string(value)) } - // Search The struct object to see if we have a field with a tag that matches the raw key coming off the file input - // This is the best way I've found to "search" for a a struct field based on a struct tag value. - // In this case, the /proc/vmstat keys are struct tags. - fieldToSet := refVal.FieldByNameFunc(func(name string) bool { - testField, exists := reflect.TypeOf(vmStat).Elem().FieldByName(name) - if !exists { - return false - } - if testField.Tag.Get("vmstat") == string(key) { - return true - } - return false - }) - - // This protects us from fields in /proc/vmstat that we don't have added in our struct - // This is just a way to make sure we actually found a field in the above `FieldByNameFunc` - if fieldToSet.CanSet() { - fieldToSet.SetUint(val) + sval, ok := tagMap[string(key)] + if !ok { + return nil + } + + if sval.CanSet() { + sval.SetUint(val) } return nil + }) return vmStat, err diff --git a/providers/linux/vmstat_test.go b/providers/linux/vmstat_test.go index df7a57ed..1e44cb9f 100644 --- a/providers/linux/vmstat_test.go +++ b/providers/linux/vmstat_test.go @@ -164,7 +164,6 @@ func TestVmStatParse(t *testing.T) { if err != nil { t.Fatal(err) } - // Check a few values assert.Equal(t, uint64(8348560), data.SlabsScanned) assert.Equal(t, uint64(0), data.SwapRa) diff --git a/types/host.go b/types/host.go index 92b2a6ff..08722f40 100644 --- a/types/host.go +++ b/types/host.go @@ -94,175 +94,175 @@ type HostMemoryInfo struct { // with different kernel versions. If we don't have a field in vmstat, // the field in the struct will just be blank. The comments represent kernel versions. type VMStatInfo struct { - NrFreePages uint64 `vmstat:"nr_free_pages"` // (since Linux 2.6.31) - NrAllocBatch uint64 `vmstat:"nr_alloc_batch"` // (since Linux 3.12) - NrInactiveAnon uint64 `vmstat:"nr_inactive_anon"` // (since Linux 2.6.28) - NrActiveAnon uint64 `vmstat:"nr_active_anon"` // (since Linux 2.6.28) - NrInactiveFile uint64 `vmstat:"nr_inactive_file"` // (since Linux 2.6.28) - NrActiveFile uint64 `vmstat:"nr_active_file"` // (since Linux 2.6.28) - NrUnevictable uint64 `vmstat:"nr_unevictable"` // (since Linux 2.6.28) - NrMlock uint64 `vmstat:"nr_mlock"` // (since Linux 2.6.28) - NrAnonPages uint64 `vmstat:"nr_anon_pages"` // (since Linux 2.6.18) - NrMapped uint64 `vmstat:"nr_mapped"` // (since Linux 2.6.0) - NrFilePages uint64 `vmstat:"nr_file_pages"` // (since Linux 2.6.18) - NrDirty uint64 `vmstat:"nr_dirty"` // (since Linux 2.6.0) - NrWriteback uint64 `vmstat:"nr_writeback"` // (since Linux 2.6.0) - NrSlabReclaimable uint64 `vmstat:"nr_slab_reclaimable"` // (since Linux 2.6.19) - NrSlabUnreclaimable uint64 `vmstat:"nr_slab_unreclaimable"` // (since Linux 2.6.19) - NrPageTablePages uint64 `vmstat:"nr_page_table_pages"` // (since Linux 2.6.0) - NrKernelStack uint64 `vmstat:"nr_kernel_stack"` // (since Linux 2.6.32) Amount of memory allocated to kernel stacks. - NrUnstable uint64 `vmstat:"nr_unstable"` // (since Linux 2.6.0) - NrBounce uint64 `vmstat:"nr_bounce"` // (since Linux 2.6.12) - NrVmscanWrite uint64 `vmstat:"nr_vmscan_write"` // (since Linux 2.6.19) - NrVmscanImmediateReclaim uint64 `vmstat:"nr_vmscan_immediate_reclaim"` // (since Linux 3.2) - NrWritebackTemp uint64 `vmstat:"nr_writeback_temp"` // (since Linux 2.6.26) - NrIsolatedAnon uint64 `vmstat:"nr_isolated_anon"` // (since Linux 2.6.32) - NrIsolatedFile uint64 `vmstat:"nr_isolated_file"` // (since Linux 2.6.32) - NrShmem uint64 `vmstat:"nr_shmem"` // (since Linux 2.6.32) Pages used by shmem and tmpfs(5). - NrDirtied uint64 `vmstat:"nr_dirtied"` // (since Linux 2.6.37) - NrWritten uint64 `vmstat:"nr_written"` // (since Linux 2.6.37) - NrPagesScanned uint64 `vmstat:"nr_pages_scanned"` // (since Linux 3.17) - NumaHit uint64 `vmstat:"numa_hit"` // (since Linux 2.6.18) - NumaMiss uint64 `vmstat:"numa_miss"` // (since Linux 2.6.18) - NumaForeign uint64 `vmstat:"numa_foreign"` // (since Linux 2.6.18) - NumaInterleave uint64 `vmstat:"numa_interleave"` // (since Linux 2.6.18) - NumaLocal uint64 `vmstat:"numa_local"` // (since Linux 2.6.18) - NumaOther uint64 `vmstat:"numa_other"` // (since Linux 2.6.18) - WorkingsetRefault uint64 `vmstat:"workingset_refault"` // (since Linux 3.15) - WorkingsetActivate uint64 `vmstat:"workingset_activate"` // (since Linux 3.15) - WorkingsetNodereclaim uint64 `vmstat:"workingset_nodereclaim"` // (since Linux 3.15) - NrAnonTransparentHugepages uint64 `vmstat:"nr_anon_transparent_hugepages"` // (since Linux 2.6.38) - NrFreeCma uint64 `vmstat:"nr_free_cma"` // (since Linux 3.7) Number of free CMA (Contiguous Memory Allocator) pages. - NrDirtyThreshold uint64 `vmstat:"nr_dirty_threshold"` // (since Linux 2.6.37) - NrDirtyBackgroundThreshold uint64 `vmstat:"nr_dirty_background_threshold"` // (since Linux 2.6.37) - Pgpgin uint64 `vmstat:"pgpgin"` // (since Linux 2.6.0) - Pgpgout uint64 `vmstat:"pgpgout"` // (since Linux 2.6.0) - Pswpin uint64 `vmstat:"pswpin"` // (since Linux 2.6.0) - Pswpout uint64 `vmstat:"pswpout"` // (since Linux 2.6.0) - PgallocDma uint64 `vmstat:"pgalloc_dma"` // (since Linux 2.6.5) - PgallocDma32 uint64 `vmstat:"pgalloc_dma32"` // (since Linux 2.6.16) - PgallocNormal uint64 `vmstat:"pgalloc_normal"` // (since Linux 2.6.5) - PgallocHigh uint64 `vmstat:"pgalloc_high"` // (since Linux 2.6.5) - PgallocMovable uint64 `vmstat:"pgalloc_movable"` // (since Linux 2.6.23) - Pgfree uint64 `vmstat:"pgfree"` // (since Linux 2.6.0) - Pgactivate uint64 `vmstat:"pgactivate"` // (since Linux 2.6.0) - Pgdeactivate uint64 `vmstat:"pgdeactivate"` // (since Linux 2.6.0) - Pgfault uint64 `vmstat:"pgfault"` // (since Linux 2.6.0) - Pgmajfault uint64 `vmstat:"pgmajfault"` // (since Linux 2.6.0) - PgrefillDma uint64 `vmstat:"pgrefill_dma"` // (since Linux 2.6.5) - PgrefillDma32 uint64 `vmstat:"pgrefill_dma32"` // (since Linux 2.6.16) - PgrefillNormal uint64 `vmstat:"pgrefill_normal"` // (since Linux 2.6.5) - PgrefillHigh uint64 `vmstat:"pgrefill_high"` // (since Linux 2.6.5) - PgrefillMovable uint64 `vmstat:"pgrefill_movable"` // (since Linux 2.6.23) - PgstealKswapdDma uint64 `vmstat:"pgsteal_kswapd_dma"` // (since Linux 3.4) - PgstealKswapdDma32 uint64 `vmstat:"pgsteal_kswapd_dma32"` // (since Linux 3.4) - PgstealKswapdNormal uint64 `vmstat:"pgsteal_kswapd_normal"` // (since Linux 3.4) - PgstealKswapdHigh uint64 `vmstat:"pgsteal_kswapd_high"` // (since Linux 3.4) - PgstealKswapdMovable uint64 `vmstat:"pgsteal_kswapd_movable"` // (since Linux 3.4) - PgstealDirectDma uint64 `vmstat:"pgsteal_direct_dma"` - PgstealDirectDma32 uint64 `vmstat:"pgsteal_direct_dma32"` // (since Linux 3.4) - PgstealDirectNormal uint64 `vmstat:"pgsteal_direct_normal"` // (since Linux 3.4) - PgstealDirectHigh uint64 `vmstat:"pgsteal_direct_high"` // (since Linux 3.4) - PgstealDirectMovable uint64 `vmstat:"pgsteal_direct_movable"` // (since Linux 2.6.23) - PgscanKswapdDma uint64 `vmstat:"pgscan_kswapd_dma"` - PgscanKswapdDma32 uint64 `vmstat:"pgscan_kswapd_dma32"` // (since Linux 2.6.16) - PgscanKswapdNormal uint64 `vmstat:"pgscan_kswapd_normal"` // (since Linux 2.6.5) - PgscanKswapdHigh uint64 `vmstat:"pgscan_kswapd_high"` - PgscanKswapdMovable uint64 `vmstat:"pgscan_kswapd_movable"` // (since Linux 2.6.23) - PgscanDirectDma uint64 `vmstat:"pgscan_direct_dma"` // - PgscanDirectDma32 uint64 `vmstat:"pgscan_direct_dma32"` // (since Linux 2.6.16) - PgscanDirectNormal uint64 `vmstat:"pgscan_direct_normal"` - PgscanDirectHigh uint64 `vmstat:"pgscan_direct_high"` - PgscanDirectMovable uint64 `vmstat:"pgscan_direct_movable"` // (since Linux 2.6.23) - PgscanDirectThrottle uint64 `vmstat:"pgscan_direct_throttle"` // (since Linux 3.6) - ZoneReclaimFailed uint64 `vmstat:"zone_reclaim_failed"` // (since linux 2.6.31) - Pginodesteal uint64 `vmstat:"pginodesteal"` // (since linux 2.6.0) - SlabsScanned uint64 `vmstat:"slabs_scanned"` // (since linux 2.6.5) - KswapdInodesteal uint64 `vmstat:"kswapd_inodesteal"` // (since linux 2.6.0) - KswapdLowWmarkHitQuickly uint64 `vmstat:"kswapd_low_wmark_hit_quickly"` // (since 2.6.33) - KswapdHighWmarkHitQuickly uint64 `vmstat:"kswapd_high_wmark_hit_quickly"` // (since 2.6.33) - Pageoutrun uint64 `vmstat:"pageoutrun"` // (since Linux 2.6.0) - Allocstall uint64 `vmstat:"allocstall"` // (since Linux 2.6.0) - Pgrotated uint64 `vmstat:"pgrotated"` // (since Linux 2.6.0) - DropPagecache uint64 `vmstat:"drop_pagecache"` // (since Linux 3.15) - DropSlab uint64 `vmstat:"drop_slab"` // (since Linux 3.15) - NumaPteUpdates uint64 `vmstat:"numa_pte_updates"` // (since Linux 3.8) - NumaHugePteUpdates uint64 `vmstat:"numa_huge_pte_updates"` // (since Linux 3.13) - NumaHintFaults uint64 `vmstat:"numa_hint_faults"` // (since Linux 3.8) - NumaHintFaultsLocal uint64 `vmstat:"numa_hint_faults_local"` // (since Linux 3.8) - NumaPagesMigrated uint64 `vmstat:"numa_pages_migrated"` // (since Linux 3.8) - PgmigrateSuccess uint64 `vmstat:"pgmigrate_success"` // (since Linux 3.8) - PgmigrateFail uint64 `vmstat:"pgmigrate_fail"` // (since Linux 3.8) - CompactMigrateScanned uint64 `vmstat:"compact_migrate_scanned"` // (since Linux 3.8) - CompactFreeScanned uint64 `vmstat:"compact_free_scanned"` // (since Linux 3.8) - CompactIsolated uint64 `vmstat:"compact_isolated"` // (since Linux 3.8) - CompactStall uint64 `vmstat:"compact_stall"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - CompactFail uint64 `vmstat:"compact_fail"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - CompactSuccess uint64 `vmstat:"compact_success"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - HtlbBuddyAllocSuccess uint64 `vmstat:"htlb_buddy_alloc_success"` // (since Linux 2.6.26) - HtlbBuddyAllocFail uint64 `vmstat:"htlb_buddy_alloc_fail"` // (since Linux 2.6.26) - UnevictablePgsCulled uint64 `vmstat:"unevictable_pgs_culled"` // (since Linux 2.6.28) - UnevictablePgsScanned uint64 `vmstat:"unevictable_pgs_scanned"` // (since Linux 2.6.28) - UnevictablePgsRescued uint64 `vmstat:"unevictable_pgs_rescued"` // (since Linux 2.6.28) - UnevictablePgsMlocked uint64 `vmstat:"unevictable_pgs_mlocked"` // (since Linux 2.6.28) - UnevictablePgsMunlocked uint64 `vmstat:"unevictable_pgs_munlocked"` // (since Linux 2.6.28) - UnevictablePgsCleared uint64 `vmstat:"unevictable_pgs_cleared"` // (since Linux 2.6.28) - UnevictablePgsStranded uint64 `vmstat:"unevictable_pgs_stranded"` // (since Linux 2.6.28) - ThpFaultAlloc uint64 `vmstat:"thp_fault_alloc"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - ThpFaultFallback uint64 `vmstat:"thp_fault_fallback"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - ThpCollapseAlloc uint64 `vmstat:"thp_collapse_alloc"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - ThpCollapseAllocFailed uint64 `vmstat:"thp_collapse_alloc_failed"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - ThpSplit uint64 `vmstat:"thp_split"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - ThpZeroPageAlloc uint64 `vmstat:"thp_zero_page_alloc"` // (since Linux 3.8) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - ThpZeroPageAllocFailed uint64 `vmstat:"thp_zero_page_alloc_failed"` // (since Linux 3.8) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. - BalloonInflate uint64 `vmstat:"balloon_inflate"` // (since Linux 3.18) - BalloonDeflate uint64 `vmstat:"balloon_deflate"` // (since Linux 3.18) - BalloonMigrate uint64 `vmstat:"balloon_migrate"` // (since Linux 3.18) - NrTlbRemoteFlush uint64 `vmstat:"nr_tlb_remote_flush"` // (since Linux 3.12) - NrTlbRemoteFlushReceived uint64 `vmstat:"nr_tlb_remote_flush_received"` // (since Linux 3.12) - NrTlbLocalFlushAll uint64 `vmstat:"nr_tlb_local_flush_all"` // (since Linux 3.12) - NrTlbLocalFlushOne uint64 `vmstat:"nr_tlb_local_flush_one"` // (since Linux 3.12) - VmacacheFindCalls uint64 `vmstat:"vmacache_find_calls"` // (since Linux 3.16) - VmacacheFindHits uint64 `vmstat:"vmacache_find_hits"` // (since Linux 3.16) - VmacacheFullFlushes uint64 `vmstat:"vmacache_full_flushes"` // (since Linux 3.19) + NrFreePages uint64 `json:"nr_free_pages"` // (since Linux 2.6.31) + NrAllocBatch uint64 `json:"nr_alloc_batch"` // (since Linux 3.12) + NrInactiveAnon uint64 `json:"nr_inactive_anon"` // (since Linux 2.6.28) + NrActiveAnon uint64 `json:"nr_active_anon"` // (since Linux 2.6.28) + NrInactiveFile uint64 `json:"nr_inactive_file"` // (since Linux 2.6.28) + NrActiveFile uint64 `json:"nr_active_file"` // (since Linux 2.6.28) + NrUnevictable uint64 `json:"nr_unevictable"` // (since Linux 2.6.28) + NrMlock uint64 `json:"nr_mlock"` // (since Linux 2.6.28) + NrAnonPages uint64 `json:"nr_anon_pages"` // (since Linux 2.6.18) + NrMapped uint64 `json:"nr_mapped"` // (since Linux 2.6.0) + NrFilePages uint64 `json:"nr_file_pages"` // (since Linux 2.6.18) + NrDirty uint64 `json:"nr_dirty"` // (since Linux 2.6.0) + NrWriteback uint64 `json:"nr_writeback"` // (since Linux 2.6.0) + NrSlabReclaimable uint64 `json:"nr_slab_reclaimable"` // (since Linux 2.6.19) + NrSlabUnreclaimable uint64 `json:"nr_slab_unreclaimable"` // (since Linux 2.6.19) + NrPageTablePages uint64 `json:"nr_page_table_pages"` // (since Linux 2.6.0) + NrKernelStack uint64 `json:"nr_kernel_stack"` // (since Linux 2.6.32) Amount of memory allocated to kernel stacks. + NrUnstable uint64 `json:"nr_unstable"` // (since Linux 2.6.0) + NrBounce uint64 `json:"nr_bounce"` // (since Linux 2.6.12) + NrVmscanWrite uint64 `json:"nr_vmscan_write"` // (since Linux 2.6.19) + NrVmscanImmediateReclaim uint64 `json:"nr_vmscan_immediate_reclaim"` // (since Linux 3.2) + NrWritebackTemp uint64 `json:"nr_writeback_temp"` // (since Linux 2.6.26) + NrIsolatedAnon uint64 `json:"nr_isolated_anon"` // (since Linux 2.6.32) + NrIsolatedFile uint64 `json:"nr_isolated_file"` // (since Linux 2.6.32) + NrShmem uint64 `json:"nr_shmem"` // (since Linux 2.6.32) Pages used by shmem and tmpfs(5). + NrDirtied uint64 `json:"nr_dirtied"` // (since Linux 2.6.37) + NrWritten uint64 `json:"nr_written"` // (since Linux 2.6.37) + NrPagesScanned uint64 `json:"nr_pages_scanned"` // (since Linux 3.17) + NumaHit uint64 `json:"numa_hit"` // (since Linux 2.6.18) + NumaMiss uint64 `json:"numa_miss"` // (since Linux 2.6.18) + NumaForeign uint64 `json:"numa_foreign"` // (since Linux 2.6.18) + NumaInterleave uint64 `json:"numa_interleave"` // (since Linux 2.6.18) + NumaLocal uint64 `json:"numa_local"` // (since Linux 2.6.18) + NumaOther uint64 `json:"numa_other"` // (since Linux 2.6.18) + WorkingsetRefault uint64 `json:"workingset_refault"` // (since Linux 3.15) + WorkingsetActivate uint64 `json:"workingset_activate"` // (since Linux 3.15) + WorkingsetNodereclaim uint64 `json:"workingset_nodereclaim"` // (since Linux 3.15) + NrAnonTransparentHugepages uint64 `json:"nr_anon_transparent_hugepages"` // (since Linux 2.6.38) + NrFreeCma uint64 `json:"nr_free_cma"` // (since Linux 3.7) Number of free CMA (Contiguous Memory Allocator) pages. + NrDirtyThreshold uint64 `json:"nr_dirty_threshold"` // (since Linux 2.6.37) + NrDirtyBackgroundThreshold uint64 `json:"nr_dirty_background_threshold"` // (since Linux 2.6.37) + Pgpgin uint64 `json:"pgpgin"` // (since Linux 2.6.0) + Pgpgout uint64 `json:"pgpgout"` // (since Linux 2.6.0) + Pswpin uint64 `json:"pswpin"` // (since Linux 2.6.0) + Pswpout uint64 `json:"pswpout"` // (since Linux 2.6.0) + PgallocDma uint64 `json:"pgalloc_dma"` // (since Linux 2.6.5) + PgallocDma32 uint64 `json:"pgalloc_dma32"` // (since Linux 2.6.16) + PgallocNormal uint64 `json:"pgalloc_normal"` // (since Linux 2.6.5) + PgallocHigh uint64 `json:"pgalloc_high"` // (since Linux 2.6.5) + PgallocMovable uint64 `json:"pgalloc_movable"` // (since Linux 2.6.23) + Pgfree uint64 `json:"pgfree"` // (since Linux 2.6.0) + Pgactivate uint64 `json:"pgactivate"` // (since Linux 2.6.0) + Pgdeactivate uint64 `json:"pgdeactivate"` // (since Linux 2.6.0) + Pgfault uint64 `json:"pgfault"` // (since Linux 2.6.0) + Pgmajfault uint64 `json:"pgmajfault"` // (since Linux 2.6.0) + PgrefillDma uint64 `json:"pgrefill_dma"` // (since Linux 2.6.5) + PgrefillDma32 uint64 `json:"pgrefill_dma32"` // (since Linux 2.6.16) + PgrefillNormal uint64 `json:"pgrefill_normal"` // (since Linux 2.6.5) + PgrefillHigh uint64 `json:"pgrefill_high"` // (since Linux 2.6.5) + PgrefillMovable uint64 `json:"pgrefill_movable"` // (since Linux 2.6.23) + PgstealKswapdDma uint64 `json:"pgsteal_kswapd_dma"` // (since Linux 3.4) + PgstealKswapdDma32 uint64 `json:"pgsteal_kswapd_dma32"` // (since Linux 3.4) + PgstealKswapdNormal uint64 `json:"pgsteal_kswapd_normal"` // (since Linux 3.4) + PgstealKswapdHigh uint64 `json:"pgsteal_kswapd_high"` // (since Linux 3.4) + PgstealKswapdMovable uint64 `json:"pgsteal_kswapd_movable"` // (since Linux 3.4) + PgstealDirectDma uint64 `json:"pgsteal_direct_dma"` + PgstealDirectDma32 uint64 `json:"pgsteal_direct_dma32"` // (since Linux 3.4) + PgstealDirectNormal uint64 `json:"pgsteal_direct_normal"` // (since Linux 3.4) + PgstealDirectHigh uint64 `json:"pgsteal_direct_high"` // (since Linux 3.4) + PgstealDirectMovable uint64 `json:"pgsteal_direct_movable"` // (since Linux 2.6.23) + PgscanKswapdDma uint64 `json:"pgscan_kswapd_dma"` + PgscanKswapdDma32 uint64 `json:"pgscan_kswapd_dma32"` // (since Linux 2.6.16) + PgscanKswapdNormal uint64 `json:"pgscan_kswapd_normal"` // (since Linux 2.6.5) + PgscanKswapdHigh uint64 `json:"pgscan_kswapd_high"` + PgscanKswapdMovable uint64 `json:"pgscan_kswapd_movable"` // (since Linux 2.6.23) + PgscanDirectDma uint64 `json:"pgscan_direct_dma"` // + PgscanDirectDma32 uint64 `json:"pgscan_direct_dma32"` // (since Linux 2.6.16) + PgscanDirectNormal uint64 `json:"pgscan_direct_normal"` + PgscanDirectHigh uint64 `json:"pgscan_direct_high"` + PgscanDirectMovable uint64 `json:"pgscan_direct_movable"` // (since Linux 2.6.23) + PgscanDirectThrottle uint64 `json:"pgscan_direct_throttle"` // (since Linux 3.6) + ZoneReclaimFailed uint64 `json:"zone_reclaim_failed"` // (since linux 2.6.31) + Pginodesteal uint64 `json:"pginodesteal"` // (since linux 2.6.0) + SlabsScanned uint64 `json:"slabs_scanned"` // (since linux 2.6.5) + KswapdInodesteal uint64 `json:"kswapd_inodesteal"` // (since linux 2.6.0) + KswapdLowWmarkHitQuickly uint64 `json:"kswapd_low_wmark_hit_quickly"` // (since 2.6.33) + KswapdHighWmarkHitQuickly uint64 `json:"kswapd_high_wmark_hit_quickly"` // (since 2.6.33) + Pageoutrun uint64 `json:"pageoutrun"` // (since Linux 2.6.0) + Allocstall uint64 `json:"allocstall"` // (since Linux 2.6.0) + Pgrotated uint64 `json:"pgrotated"` // (since Linux 2.6.0) + DropPagecache uint64 `json:"drop_pagecache"` // (since Linux 3.15) + DropSlab uint64 `json:"drop_slab"` // (since Linux 3.15) + NumaPteUpdates uint64 `json:"numa_pte_updates"` // (since Linux 3.8) + NumaHugePteUpdates uint64 `json:"numa_huge_pte_updates"` // (since Linux 3.13) + NumaHintFaults uint64 `json:"numa_hint_faults"` // (since Linux 3.8) + NumaHintFaultsLocal uint64 `json:"numa_hint_faults_local"` // (since Linux 3.8) + NumaPagesMigrated uint64 `json:"numa_pages_migrated"` // (since Linux 3.8) + PgmigrateSuccess uint64 `json:"pgmigrate_success"` // (since Linux 3.8) + PgmigrateFail uint64 `json:"pgmigrate_fail"` // (since Linux 3.8) + CompactMigrateScanned uint64 `json:"compact_migrate_scanned"` // (since Linux 3.8) + CompactFreeScanned uint64 `json:"compact_free_scanned"` // (since Linux 3.8) + CompactIsolated uint64 `json:"compact_isolated"` // (since Linux 3.8) + CompactStall uint64 `json:"compact_stall"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + CompactFail uint64 `json:"compact_fail"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + CompactSuccess uint64 `json:"compact_success"` // (since Linux 2.6.35) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + HtlbBuddyAllocSuccess uint64 `json:"htlb_buddy_alloc_success"` // (since Linux 2.6.26) + HtlbBuddyAllocFail uint64 `json:"htlb_buddy_alloc_fail"` // (since Linux 2.6.26) + UnevictablePgsCulled uint64 `json:"unevictable_pgs_culled"` // (since Linux 2.6.28) + UnevictablePgsScanned uint64 `json:"unevictable_pgs_scanned"` // (since Linux 2.6.28) + UnevictablePgsRescued uint64 `json:"unevictable_pgs_rescued"` // (since Linux 2.6.28) + UnevictablePgsMlocked uint64 `json:"unevictable_pgs_mlocked"` // (since Linux 2.6.28) + UnevictablePgsMunlocked uint64 `json:"unevictable_pgs_munlocked"` // (since Linux 2.6.28) + UnevictablePgsCleared uint64 `json:"unevictable_pgs_cleared"` // (since Linux 2.6.28) + UnevictablePgsStranded uint64 `json:"unevictable_pgs_stranded"` // (since Linux 2.6.28) + ThpFaultAlloc uint64 `json:"thp_fault_alloc"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpFaultFallback uint64 `json:"thp_fault_fallback"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpCollapseAlloc uint64 `json:"thp_collapse_alloc"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpCollapseAllocFailed uint64 `json:"thp_collapse_alloc_failed"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpSplit uint64 `json:"thp_split"` // (since Linux 2.6.39) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpZeroPageAlloc uint64 `json:"thp_zero_page_alloc"` // (since Linux 3.8) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + ThpZeroPageAllocFailed uint64 `json:"thp_zero_page_alloc_failed"` // (since Linux 3.8) See the kernel source file Documentation/admin-guide/mm/transhuge.rst. + BalloonInflate uint64 `json:"balloon_inflate"` // (since Linux 3.18) + BalloonDeflate uint64 `json:"balloon_deflate"` // (since Linux 3.18) + BalloonMigrate uint64 `json:"balloon_migrate"` // (since Linux 3.18) + NrTlbRemoteFlush uint64 `json:"nr_tlb_remote_flush"` // (since Linux 3.12) + NrTlbRemoteFlushReceived uint64 `json:"nr_tlb_remote_flush_received"` // (since Linux 3.12) + NrTlbLocalFlushAll uint64 `json:"nr_tlb_local_flush_all"` // (since Linux 3.12) + NrTlbLocalFlushOne uint64 `json:"nr_tlb_local_flush_one"` // (since Linux 3.12) + VmacacheFindCalls uint64 `json:"vmacache_find_calls"` // (since Linux 3.16) + VmacacheFindHits uint64 `json:"vmacache_find_hits"` // (since Linux 3.16) + VmacacheFullFlushes uint64 `json:"vmacache_full_flushes"` // (since Linux 3.19) // the following fields are not documented in `man 5 proc` as of 4.15 - NrZoneInactiveAnon uint64 `vmstat:"nr_zone_inactive_anon"` - NrZoneActiveAnon uint64 `vmstat:"nr_zone_active_anon"` - NrZoneInactiveFile uint64 `vmstat:"nr_zone_inactive_file"` - NrZoneActiveFile uint64 `vmstat:"nr_zone_active_file"` - NrZoneUnevictable uint64 `vmstat:"nr_zone_unevictable"` - NrZoneWritePending uint64 `vmstat:"nr_zone_write_pending"` - NrZspages uint64 `vmstat:"nr_zspages"` - NrShmemHugepages uint64 `vmstat:"nr_shmem_hugepages"` - NrShmemPmdmapped uint64 `vmstat:"nr_shmem_pmdmapped"` - AllocstallDma uint64 `vmstat:"allocstall_dma"` - AllocstallDma32 uint64 `vmstat:"allocstall_dma32"` - AllocstallNormal uint64 `vmstat:"allocstall_normal"` - AllocstallMovable uint64 `vmstat:"allocstall_movable"` - PgskipDma uint64 `vmstat:"pgskip_dma"` - PgskipDma32 uint64 `vmstat:"pgskip_dma32"` - PgskipNormal uint64 `vmstat:"pgskip_normal"` - PgskipMovable uint64 `vmstat:"pgskip_movable"` - Pglazyfree uint64 `vmstat:"pglazyfree"` - Pglazyfreed uint64 `vmstat:"pglazyfreed"` - Pgrefill uint64 `vmstat:"pgrefill"` - PgstealKswapd uint64 `vmstat:"pgsteal_kswapd"` - PgstealDirect uint64 `vmstat:"pgsteal_direct"` - PgscanKswapd uint64 `vmstat:"pgscan_kswapd"` - PgscanDirect uint64 `vmstat:"pgscan_direct"` - OomKill uint64 `vmstat:"oom_kill"` - CompactDaemonWake uint64 `vmstat:"compact_daemon_wake"` - CompactDaemonMigrateScanned uint64 `vmstat:"compact_daemon_migrate_scanned"` - CompactDaemonFreeScanned uint64 `vmstat:"compact_daemon_free_scanned"` - ThpFileAlloc uint64 `vmstat:"thp_file_alloc"` - ThpFileMapped uint64 `vmstat:"thp_file_mapped"` - ThpSplitPage uint64 `vmstat:"thp_split_page"` - ThpSplitPageFailed uint64 `vmstat:"thp_split_page_failed"` - ThpDeferredSplitPage uint64 `vmstat:"thp_deferred_split_page"` - ThpSplitPmd uint64 `vmstat:"thp_split_pmd"` - ThpSplitPud uint64 `vmstat:"thp_split_pud"` - ThpSwpout uint64 `vmstat:"thp_swpout"` - ThpSwpoutFallback uint64 `vmstat:"thp_swpout_fallback"` - SwapRa uint64 `vmstat:"swap_ra"` - SwapRaHit uint64 `vmstat:"swap_ra_hit"` + NrZoneInactiveAnon uint64 `json:"nr_zone_inactive_anon"` + NrZoneActiveAnon uint64 `json:"nr_zone_active_anon"` + NrZoneInactiveFile uint64 `json:"nr_zone_inactive_file"` + NrZoneActiveFile uint64 `json:"nr_zone_active_file"` + NrZoneUnevictable uint64 `json:"nr_zone_unevictable"` + NrZoneWritePending uint64 `json:"nr_zone_write_pending"` + NrZspages uint64 `json:"nr_zspages"` + NrShmemHugepages uint64 `json:"nr_shmem_hugepages"` + NrShmemPmdmapped uint64 `json:"nr_shmem_pmdmapped"` + AllocstallDma uint64 `json:"allocstall_dma"` + AllocstallDma32 uint64 `json:"allocstall_dma32"` + AllocstallNormal uint64 `json:"allocstall_normal"` + AllocstallMovable uint64 `json:"allocstall_movable"` + PgskipDma uint64 `json:"pgskip_dma"` + PgskipDma32 uint64 `json:"pgskip_dma32"` + PgskipNormal uint64 `json:"pgskip_normal"` + PgskipMovable uint64 `json:"pgskip_movable"` + Pglazyfree uint64 `json:"pglazyfree"` + Pglazyfreed uint64 `json:"pglazyfreed"` + Pgrefill uint64 `json:"pgrefill"` + PgstealKswapd uint64 `json:"pgsteal_kswapd"` + PgstealDirect uint64 `json:"pgsteal_direct"` + PgscanKswapd uint64 `json:"pgscan_kswapd"` + PgscanDirect uint64 `json:"pgscan_direct"` + OomKill uint64 `json:"oom_kill"` + CompactDaemonWake uint64 `json:"compact_daemon_wake"` + CompactDaemonMigrateScanned uint64 `json:"compact_daemon_migrate_scanned"` + CompactDaemonFreeScanned uint64 `json:"compact_daemon_free_scanned"` + ThpFileAlloc uint64 `json:"thp_file_alloc"` + ThpFileMapped uint64 `json:"thp_file_mapped"` + ThpSplitPage uint64 `json:"thp_split_page"` + ThpSplitPageFailed uint64 `json:"thp_split_page_failed"` + ThpDeferredSplitPage uint64 `json:"thp_deferred_split_page"` + ThpSplitPmd uint64 `json:"thp_split_pmd"` + ThpSplitPud uint64 `json:"thp_split_pud"` + ThpSwpout uint64 `json:"thp_swpout"` + ThpSwpoutFallback uint64 `json:"thp_swpout_fallback"` + SwapRa uint64 `json:"swap_ra"` + SwapRaHit uint64 `json:"swap_ra_hit"` } From e65b978aec046f703ea5fa5d63c0b683b7fb6d17 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Fri, 16 Aug 2019 19:06:34 -0500 Subject: [PATCH 09/13] move tag-index map to init() --- providers/linux/vmstat.go | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go index 2f0898ea..3c52aeca 100644 --- a/providers/linux/vmstat.go +++ b/providers/linux/vmstat.go @@ -25,18 +25,27 @@ import ( "github.com/elastic/go-sysinfo/types" ) +// vmstatTagToFieldIndex contains a mapping of json struct tags to struct field indices. +var vmstatTagToFieldIndex = make(map[string]int) + +func init() { + var vmstat types.VMStatInfo + val := reflect.ValueOf(vmstat) + typ := reflect.TypeOf(vmstat) + + for i := 0; i < val.NumField(); i++ { + field := typ.Field(i) + if tag := field.Tag.Get("json"); tag != "" { + vmstatTagToFieldIndex[tag] = i + } + } +} + // parseVMStat parses the contents of /proc/vmstat func parseVMStat(content []byte) (*types.VMStatInfo, error) { - vmStat := &types.VMStatInfo{} - refVal := reflect.ValueOf(vmStat).Elem() - tagMap := make(map[string]*reflect.Value) - - //iterate over the struct and make a map of tags->values - for index := 0; index < refVal.NumField(); index++ { - tag := refVal.Type().Field(index).Tag.Get("json") - val := refVal.Field(index) - tagMap[tag] = &val - } + + var vmStat types.VMStatInfo + refValues := reflect.ValueOf(&vmStat).Elem() err := parseKeyValue(content, " ", func(key, value []byte) error { // turn our []byte value into an int @@ -45,11 +54,13 @@ func parseVMStat(content []byte) (*types.VMStatInfo, error) { return errors.Wrapf(err, "failed to parse %v value of %v", string(key), string(value)) } - sval, ok := tagMap[string(key)] + idx, ok := vmstatTagToFieldIndex[string(key)] if !ok { return nil } + sval := refValues.Field(idx) + if sval.CanSet() { sval.SetUint(val) } @@ -57,5 +68,5 @@ func parseVMStat(content []byte) (*types.VMStatInfo, error) { }) - return vmStat, err + return &vmStat, err } From acdbe43be701ea3731425be827b2a1c952221b59 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Tue, 20 Aug 2019 12:37:35 -0500 Subject: [PATCH 10/13] add newline --- providers/linux/vmstat.go | 1 - 1 file changed, 1 deletion(-) diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go index 3c52aeca..04de46fc 100644 --- a/providers/linux/vmstat.go +++ b/providers/linux/vmstat.go @@ -43,7 +43,6 @@ func init() { // parseVMStat parses the contents of /proc/vmstat func parseVMStat(content []byte) (*types.VMStatInfo, error) { - var vmStat types.VMStatInfo refValues := reflect.ValueOf(&vmStat).Elem() From 078af54baeab405da5a8406df01e5dac13eb4e84 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Tue, 20 Aug 2019 15:17:59 -0500 Subject: [PATCH 11/13] comment cleanup --- providers/linux/host_linux.go | 2 +- providers/linux/vmstat.go | 3 +-- types/host.go | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 335fb0dc..19325b02 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -71,7 +71,7 @@ func (h *host) Memory() (*types.HostMemoryInfo, error) { return parseMemInfo(content) } -// VMStat reports data from /proc/vmstat on linux +// VMStat reports data from /proc/vmstat on linux. func (h *host) VMStat() (*types.VMStatInfo, error) { content, err := ioutil.ReadFile(h.procFS.path("vmstat")) if err != nil { diff --git a/providers/linux/vmstat.go b/providers/linux/vmstat.go index 04de46fc..0a228678 100644 --- a/providers/linux/vmstat.go +++ b/providers/linux/vmstat.go @@ -41,7 +41,7 @@ func init() { } } -// parseVMStat parses the contents of /proc/vmstat +// parseVMStat parses the contents of /proc/vmstat. func parseVMStat(content []byte) (*types.VMStatInfo, error) { var vmStat types.VMStatInfo refValues := reflect.ValueOf(&vmStat).Elem() @@ -64,7 +64,6 @@ func parseVMStat(content []byte) (*types.VMStatInfo, error) { sval.SetUint(val) } return nil - }) return &vmStat, err diff --git a/types/host.go b/types/host.go index 08722f40..2f64f543 100644 --- a/types/host.go +++ b/types/host.go @@ -26,7 +26,7 @@ type Host interface { Memory() (*HostMemoryInfo, error) } -// VMStat is the interface wrapper for platforms that support /proc/vmstat +// VMStat is the interface wrapper for platforms that support /proc/vmstat. type VMStat interface { VMStat() (*VMStatInfo, error) } @@ -89,7 +89,7 @@ type HostMemoryInfo struct { Metrics map[string]uint64 `json:"raw,omitempty"` // Other memory related metrics. } -// VMStatInfo contains parsed info from /proc/vmstat +// VMStatInfo contains parsed info from /proc/vmstat. // This procfs file has expanded much over the years // with different kernel versions. If we don't have a field in vmstat, // the field in the struct will just be blank. The comments represent kernel versions. From 290ee059596848c3a54bc1ec4b93867cb7175382 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Tue, 20 Aug 2019 15:23:36 -0500 Subject: [PATCH 12/13] hostinfo formatting --- types/host.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/host.go b/types/host.go index 2f64f543..bf5b80cd 100644 --- a/types/host.go +++ b/types/host.go @@ -31,7 +31,7 @@ type VMStat interface { VMStat() (*VMStatInfo, error) } -// HostInfo contains basic host information +// HostInfo contains basic host information. type HostInfo struct { Architecture string `json:"architecture"` // Hardware architecture (e.g. x86_64, arm, ppc, mips). BootTime time.Time `json:"boot_time"` // Host boot time. From b854025064f7431bd7e4fac6019a474cef8974e9 Mon Sep 17 00:00:00 2001 From: Alex Kristiansen Date: Wed, 21 Aug 2019 13:13:06 -0500 Subject: [PATCH 13/13] add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1727d20..b74c7642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Add `VMStat` interface for Linux. [#59](https://github.com/elastic/go-sysinfo/pull/59) + ### Changed ### Deprecated