502 lines
15 KiB
Go
502 lines
15 KiB
Go
// returns data points from Win32_PerfRawData_PerfOS_Memory
|
|
// <add link to documentation here> - Win32_PerfRawData_PerfOS_Memory class
|
|
package collector
|
|
|
|
import (
|
|
"github.com/StackExchange/wmi"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/common/log"
|
|
)
|
|
|
|
func init() {
|
|
Factories["memory"] = NewMemoryCollector
|
|
}
|
|
|
|
// A MemoryCollector is a Prometheus collector for WMI Win32_PerfRawData_PerfOS_Memory metrics
|
|
type MemoryCollector struct {
|
|
AvailableBytes *prometheus.Desc
|
|
CacheBytes *prometheus.Desc
|
|
CacheBytesPeak *prometheus.Desc
|
|
CacheFaultsTotal *prometheus.Desc
|
|
CommitLimit *prometheus.Desc
|
|
CommittedBytes *prometheus.Desc
|
|
DemandZeroFaultsTotal *prometheus.Desc
|
|
FreeAndZeroPageListBytes *prometheus.Desc
|
|
FreeSystemPageTableEntries *prometheus.Desc
|
|
ModifiedPageListBytes *prometheus.Desc
|
|
PageFaultsTotal *prometheus.Desc
|
|
SwapPageReadsTotal *prometheus.Desc
|
|
SwapPagesReadTotal *prometheus.Desc
|
|
SwapPagesWrittenTotal *prometheus.Desc
|
|
SwapPageOperationsTotal *prometheus.Desc
|
|
SwapPageWritesTotal *prometheus.Desc
|
|
PoolNonpagedAllocsTotal *prometheus.Desc
|
|
PoolNonpagedBytes *prometheus.Desc
|
|
PoolPagedAllocsTotal *prometheus.Desc
|
|
PoolPagedBytes *prometheus.Desc
|
|
PoolPagedResidentBytes *prometheus.Desc
|
|
StandbyCacheCoreBytes *prometheus.Desc
|
|
StandbyCacheNormalPriorityBytes *prometheus.Desc
|
|
StandbyCacheReserveBytes *prometheus.Desc
|
|
SystemCacheResidentBytes *prometheus.Desc
|
|
SystemCodeResidentBytes *prometheus.Desc
|
|
SystemCodeTotalBytes *prometheus.Desc
|
|
SystemDriverResidentBytes *prometheus.Desc
|
|
SystemDriverTotalBytes *prometheus.Desc
|
|
TransitionFaultsTotal *prometheus.Desc
|
|
TransitionPagesRepurposedTotal *prometheus.Desc
|
|
WriteCopiesTotal *prometheus.Desc
|
|
}
|
|
|
|
// NewMemoryCollector ...
|
|
func NewMemoryCollector() (Collector, error) {
|
|
const subsystem = "memory"
|
|
|
|
return &MemoryCollector{
|
|
AvailableBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "available_bytes"),
|
|
"The amount of physical memory immediately available for allocation to a process or for system use. It is equal to the sum of memory assigned to"+
|
|
" the standby (cached), free and zero page lists (AvailableBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
CacheBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "cache_bytes"),
|
|
"(CacheBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
CacheBytesPeak: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "cache_bytes_peak"),
|
|
"(CacheBytesPeak)",
|
|
nil,
|
|
nil,
|
|
),
|
|
CacheFaultsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "cache_faults_total"),
|
|
"(CacheFaultsPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
CommitLimit: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "commit_limit"),
|
|
"(CommitLimit)",
|
|
nil,
|
|
nil,
|
|
),
|
|
CommittedBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "committed_bytes"),
|
|
"(CommittedBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
DemandZeroFaultsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "demand_zero_faults_total"),
|
|
"The number of zeroed pages required to satisfy faults. Zeroed pages, pages emptied of previously stored data and filled with zeros, are a security"+
|
|
" feature of Windows that prevent processes from seeing data stored by earlier processes that used the memory space (DemandZeroFaults)",
|
|
nil,
|
|
nil,
|
|
),
|
|
FreeAndZeroPageListBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "free_and_zero_page_list_bytes"),
|
|
"(FreeAndZeroPageListBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
FreeSystemPageTableEntries: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "free_system_page_table_entries"),
|
|
"(FreeSystemPageTableEntries)",
|
|
nil,
|
|
nil,
|
|
),
|
|
ModifiedPageListBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "modified_page_list_bytes"),
|
|
"(ModifiedPageListBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
PageFaultsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "page_faults_total"),
|
|
"(PageFaultsPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SwapPageReadsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "swap_page_reads_total"),
|
|
"Number of disk page reads (a single read operation reading several pages is still only counted once) (PageReadsPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SwapPagesReadTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "swap_pages_read_total"),
|
|
"Number of pages read across all page reads (ie counting all pages read even if they are read in a single operation) (PagesInputPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SwapPagesWrittenTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "swap_pages_written_total"),
|
|
"Number of pages written across all page writes (ie counting all pages written even if they are written in a single operation) (PagesOutputPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SwapPageOperationsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "swap_page_operations_total"),
|
|
"Total number of swap page read and writes (PagesPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SwapPageWritesTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "swap_page_writes_total"),
|
|
"Number of disk page writes (a single write operation writing several pages is still only counted once) (PageWritesPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
PoolNonpagedAllocsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "pool_nonpaged_allocs_total"),
|
|
"The number of calls to allocate space in the nonpaged pool. The nonpaged pool is an area of system memory area for objects that cannot be written"+
|
|
" to disk, and must remain in physical memory as long as they are allocated (PoolNonpagedAllocs)",
|
|
nil,
|
|
nil,
|
|
),
|
|
PoolNonpagedBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "pool_nonpaged_bytes_total"),
|
|
"(PoolNonpagedBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
PoolPagedAllocsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_allocs_total"),
|
|
"(PoolPagedAllocs)",
|
|
nil,
|
|
nil,
|
|
),
|
|
PoolPagedBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_bytes"),
|
|
"(PoolPagedBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
PoolPagedResidentBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "pool_paged_resident_bytes"),
|
|
"(PoolPagedResidentBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
StandbyCacheCoreBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_core_bytes"),
|
|
"(StandbyCacheCoreBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
StandbyCacheNormalPriorityBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_normal_priority_bytes"),
|
|
"(StandbyCacheNormalPriorityBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
StandbyCacheReserveBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "standby_cache_reserve_bytes"),
|
|
"(StandbyCacheReserveBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SystemCacheResidentBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "system_cache_resident_bytes"),
|
|
"(SystemCacheResidentBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SystemCodeResidentBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "system_code_resident_bytes"),
|
|
"(SystemCodeResidentBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SystemCodeTotalBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "system_code_total_bytes"),
|
|
"(SystemCodeTotalBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SystemDriverResidentBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "system_driver_resident_bytes"),
|
|
"(SystemDriverResidentBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
SystemDriverTotalBytes: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "system_driver_total_bytes"),
|
|
"(SystemDriverTotalBytes)",
|
|
nil,
|
|
nil,
|
|
),
|
|
TransitionFaultsTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "transition_faults_total"),
|
|
"(TransitionFaultsPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
TransitionPagesRepurposedTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "transition_pages_repurposed_total"),
|
|
"(TransitionPagesRePurposedPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
WriteCopiesTotal: prometheus.NewDesc(
|
|
prometheus.BuildFQName(Namespace, subsystem, "write_copies_total"),
|
|
"The number of page faults caused by attempting to write that were satisfied by copying the page from elsewhere in physical memory (WriteCopiesPersec)",
|
|
nil,
|
|
nil,
|
|
),
|
|
}, nil
|
|
}
|
|
|
|
// Collect sends the metric values for each metric
|
|
// to the provided prometheus Metric channel.
|
|
func (c *MemoryCollector) Collect(ch chan<- prometheus.Metric) error {
|
|
if desc, err := c.collect(ch); err != nil {
|
|
log.Error("failed collecting memory metrics:", desc, err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type Win32_PerfRawData_PerfOS_Memory struct {
|
|
AvailableBytes uint64
|
|
AvailableKBytes uint64
|
|
AvailableMBytes uint64
|
|
CacheBytes uint64
|
|
CacheBytesPeak uint64
|
|
CacheFaultsPersec uint32
|
|
CommitLimit uint64
|
|
CommittedBytes uint64
|
|
DemandZeroFaultsPersec uint32
|
|
FreeAndZeroPageListBytes uint64
|
|
FreeSystemPageTableEntries uint32
|
|
ModifiedPageListBytes uint64
|
|
PageFaultsPersec uint32
|
|
PageReadsPersec uint32
|
|
PagesInputPersec uint32
|
|
PagesOutputPersec uint32
|
|
PagesPersec uint32
|
|
PageWritesPersec uint32
|
|
PoolNonpagedAllocs uint32
|
|
PoolNonpagedBytes uint64
|
|
PoolPagedAllocs uint32
|
|
PoolPagedBytes uint64
|
|
PoolPagedResidentBytes uint64
|
|
StandbyCacheCoreBytes uint64
|
|
StandbyCacheNormalPriorityBytes uint64
|
|
StandbyCacheReserveBytes uint64
|
|
SystemCacheResidentBytes uint64
|
|
SystemCodeResidentBytes uint64
|
|
SystemCodeTotalBytes uint64
|
|
SystemDriverResidentBytes uint64
|
|
SystemDriverTotalBytes uint64
|
|
TransitionFaultsPersec uint32
|
|
TransitionPagesRePurposedPersec uint32
|
|
WriteCopiesPersec uint32
|
|
}
|
|
|
|
func (c *MemoryCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
|
var dst []Win32_PerfRawData_PerfOS_Memory
|
|
q := queryAll(&dst)
|
|
if err := wmi.Query(q, &dst); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.AvailableBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].AvailableBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.CacheBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].CacheBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.CacheBytesPeak,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].CacheBytesPeak),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.CacheFaultsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].CacheFaultsPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.CommitLimit,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].CommitLimit),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.CommittedBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].CommittedBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.DemandZeroFaultsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].DemandZeroFaultsPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.FreeAndZeroPageListBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].FreeAndZeroPageListBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.FreeSystemPageTableEntries,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].FreeSystemPageTableEntries),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.ModifiedPageListBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].ModifiedPageListBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.PageFaultsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PageFaultsPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SwapPageReadsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PageReadsPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SwapPagesReadTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PagesInputPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SwapPagesWrittenTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PagesOutputPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SwapPageOperationsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PagesPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SwapPageWritesTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PageWritesPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.PoolNonpagedAllocsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PoolNonpagedAllocs),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.PoolNonpagedBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PoolNonpagedBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.PoolPagedAllocsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PoolPagedAllocs),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.PoolPagedBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PoolPagedBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.PoolPagedResidentBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].PoolPagedResidentBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.StandbyCacheCoreBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].StandbyCacheCoreBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.StandbyCacheNormalPriorityBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].StandbyCacheNormalPriorityBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.StandbyCacheReserveBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].StandbyCacheReserveBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SystemCacheResidentBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].SystemCacheResidentBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SystemCodeResidentBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].SystemCodeResidentBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SystemCodeTotalBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].SystemCodeTotalBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SystemDriverResidentBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].SystemDriverResidentBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.SystemDriverTotalBytes,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].SystemDriverTotalBytes),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.TransitionFaultsTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].TransitionFaultsPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.TransitionPagesRepurposedTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].TransitionPagesRePurposedPersec),
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.WriteCopiesTotal,
|
|
prometheus.GaugeValue,
|
|
float64(dst[0].WriteCopiesPersec),
|
|
)
|
|
|
|
return nil, nil
|
|
}
|