From c1fff498c61c1308f68132ec281638de460a528a Mon Sep 17 00:00:00 2001 From: "Bagdon, Bill" Date: Wed, 6 Nov 2019 12:36:17 -0500 Subject: [PATCH] Create cache collector Signed-off-by: Ben Reedy --- collector/cache.go | 453 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 453 insertions(+) create mode 100644 collector/cache.go diff --git a/collector/cache.go b/collector/cache.go new file mode 100644 index 00000000..488ad8c8 --- /dev/null +++ b/collector/cache.go @@ -0,0 +1,453 @@ +package collector + +import ( + "github.com/StackExchange/wmi" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/log" +) + +func init() { + Factories["cache"] = NewCacheCollector +} + +// A CacheCollector is a Prometheus collector for WMI Win32_PerfFormattedData_PerfOS_Cache metrics +type CacheCollector struct { + AsyncCopyReadsPersec *prometheus.Desc + AsyncDataMapsPersec *prometheus.Desc + AsyncFastReadsPersec *prometheus.Desc + AsyncMDLReadsPersec *prometheus.Desc + AsyncPinReadsPersec *prometheus.Desc + CopyReadHitsPercent *prometheus.Desc + CopyReadsPersec *prometheus.Desc + DataFlushesPersec *prometheus.Desc + DataFlushPagesPersec *prometheus.Desc + DataMapHitsPercent *prometheus.Desc + DataMapPinsPersec *prometheus.Desc + DataMapsPersec *prometheus.Desc + DirtyPages *prometheus.Desc + DirtyPageThreshold *prometheus.Desc + FastReadNotPossiblesPersec *prometheus.Desc + FastReadResourceMissesPersec *prometheus.Desc + FastReadsPersec *prometheus.Desc + LazyWriteFlushesPersec *prometheus.Desc + LazyWritePagesPersec *prometheus.Desc + MDLReadHitsPercent *prometheus.Desc + MDLReadsPersec *prometheus.Desc + PinReadHitsPercent *prometheus.Desc + PinReadsPersec *prometheus.Desc + ReadAheadsPersec *prometheus.Desc + SyncCopyReadsPersec *prometheus.Desc + SyncDataMapsPersec *prometheus.Desc + SyncFastReadsPersec *prometheus.Desc + SyncMDLReadsPersec *prometheus.Desc + SyncPinReadsPersec *prometheus.Desc +} + +// NewCacheCollector ... +func NewCacheCollector() (Collector, error) { + const subsystem = "cache" + return &CacheCollector{ + AsyncCopyReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "async_copy_reads_persec"), + "(AsyncCopyReadsPersec)", + nil, + nil, + ), + AsyncDataMapsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "async_data_maps_persec"), + "(AsyncDataMapsPersec)", + nil, + nil, + ), + AsyncFastReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "async_fast_reads_persec"), + "(AsyncFastReadsPersec)", + nil, + nil, + ), + AsyncMDLReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "async_mdl_reads_persec"), + "(AsyncMDLReadsPersec)", + nil, + nil, + ), + AsyncPinReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "async_pin_reads_persec"), + "(AsyncPinReadsPersec)", + nil, + nil, + ), + CopyReadHitsPercent: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "copy_read_hits_percent"), + "(CopyReadHitsPercent)", + nil, + nil, + ), + CopyReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "copy_reads_persec"), + "(CopyReadsPersec)", + nil, + nil, + ), + DataFlushesPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "data_flushes_persec"), + "(DataFlushesPersec)", + nil, + nil, + ), + DataFlushPagesPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "data_flush_pages_persec"), + "(DataFlushPagesPersec)", + nil, + nil, + ), + DataMapHitsPercent: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "data_map_hits_percent"), + "(DataMapHitsPercent)", + nil, + nil, + ), + DataMapPinsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "data_map_pins_persec"), + "(DataMapPinsPersec)", + nil, + nil, + ), + DataMapsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "data_maps_persec"), + "(DataMapsPersec)", + nil, + nil, + ), + DirtyPages: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "dirty_pages"), + "(DirtyPages)", + nil, + nil, + ), + DirtyPageThreshold: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "dirty_page_threshold"), + "(DirtyPageThreshold)", + nil, + nil, + ), + FastReadNotPossiblesPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "fast_read_not_possibles_persec"), + "(FastReadNotPossiblesPersec)", + nil, + nil, + ), + FastReadResourceMissesPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "fast_read_resource_misses_persec"), + "(FastReadResourceMissesPersec)", + nil, + nil, + ), + FastReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "fast_reads_persec"), + "(FastReadsPersec)", + nil, + nil, + ), + LazyWriteFlushesPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "lazy_write_flushes_persec"), + "(LazyWriteFlushesPersec)", + nil, + nil, + ), + LazyWritePagesPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "lazy_write_pages_persec"), + "(LazyWritePagesPersec)", + nil, + nil, + ), + MDLReadHitsPercent: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "mdl_read_hits_percent"), + "(MDLReadHitsPercent)", + nil, + nil, + ), + MDLReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "mdl_reads_persec"), + "(MDLReadsPersec)", + nil, + nil, + ), + PinReadHitsPercent: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "pin_read_hits_percent"), + "(PinReadHitsPercent)", + nil, + nil, + ), + PinReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "pin_reads_persec"), + "(PinReadsPersec)", + nil, + nil, + ), + ReadAheadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "read_aheads_persec"), + "(ReadAheadsPersec)", + nil, + nil, + ), + SyncCopyReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "sync_copy_reads_persec"), + "(SyncCopyReadsPersec)", + nil, + nil, + ), + SyncDataMapsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "sync_data_maps_persec"), + "(SyncDataMapsPersec)", + nil, + nil, + ), + SyncFastReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "sync_fast_reads_persec"), + "(SyncFastReadsPersec)", + nil, + nil, + ), + SyncMDLReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "sync_mdl_reads_persec"), + "(SyncMDLReadsPersec)", + nil, + nil, + ), + SyncPinReadsPersec: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "sync_pin_reads_persec"), + "(SyncPinReadsPersec)", + nil, + nil, + ), + }, nil +} + +// Collect sends the metric values for each metric +// to the provided prometheus Metric channel. +func (c *CacheCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error { + if desc, err := c.collect(ch); err != nil { + log.Error("failed collecting cache metrics:", desc, err) + return err + } + return nil +} + +// Win32_PerfFormattedData_PerfOS_Cache docs: +// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85) +type Win32_PerfFormattedData_PerfOS_Cache struct { + AsyncCopyReadsPersec uint32 + AsyncDataMapsPersec uint32 + AsyncFastReadsPersec uint32 + AsyncMDLReadsPersec uint32 + AsyncPinReadsPersec uint32 + CopyReadHitsPercent uint32 + CopyReadsPersec uint32 + DataFlushesPersec uint32 + DataFlushPagesPersec uint32 + DataMapHitsPercent uint32 + DataMapPinsPersec uint32 + DataMapsPersec uint32 + DirtyPages uint64 + DirtyPageThreshold uint64 + FastReadNotPossiblesPersec uint32 + FastReadResourceMissesPersec uint32 + FastReadsPersec uint32 + LazyWriteFlushesPersec uint32 + LazyWritePagesPersec uint32 + MDLReadHitsPercent uint32 + MDLReadsPersec uint32 + PinReadHitsPercent uint32 + PinReadsPersec uint32 + ReadAheadsPersec uint32 + SyncCopyReadsPersec uint32 + SyncDataMapsPersec uint32 + SyncFastReadsPersec uint32 + SyncMDLReadsPersec uint32 + SyncPinReadsPersec uint32 +} + +func (c *CacheCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) { + var dst []Win32_PerfFormattedData_PerfOS_Cache + q := queryAll(&dst) + if err := wmi.Query(q, &dst); err != nil { + return nil, err + } + + ch <- prometheus.MustNewConstMetric( + c.AsyncCopyReadsPersec, + prometheus.GaugeValue, + float64(dst[0].AsyncCopyReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.AsyncDataMapsPersec, + prometheus.GaugeValue, + float64(dst[0].AsyncDataMapsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.AsyncFastReadsPersec, + prometheus.GaugeValue, + float64(dst[0].AsyncFastReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.AsyncMDLReadsPersec, + prometheus.GaugeValue, + float64(dst[0].AsyncMDLReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.AsyncPinReadsPersec, + prometheus.GaugeValue, + float64(dst[0].AsyncPinReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.CopyReadHitsPercent, + prometheus.GaugeValue, + float64(dst[0].CopyReadHitsPercent), + ) + + ch <- prometheus.MustNewConstMetric( + c.CopyReadsPersec, + prometheus.GaugeValue, + float64(dst[0].CopyReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.DataFlushesPersec, + prometheus.GaugeValue, + float64(dst[0].DataFlushesPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.DataFlushPagesPersec, + prometheus.GaugeValue, + float64(dst[0].DataFlushPagesPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.DataMapHitsPercent, + prometheus.GaugeValue, + float64(dst[0].DataMapHitsPercent), + ) + + ch <- prometheus.MustNewConstMetric( + c.DataMapPinsPersec, + prometheus.GaugeValue, + float64(dst[0].DataMapPinsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.DataMapsPersec, + prometheus.GaugeValue, + float64(dst[0].DataMapsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.DirtyPages, + prometheus.GaugeValue, + float64(dst[0].DirtyPages), + ) + + ch <- prometheus.MustNewConstMetric( + c.DirtyPageThreshold, + prometheus.GaugeValue, + float64(dst[0].DirtyPageThreshold), + ) + + ch <- prometheus.MustNewConstMetric( + c.FastReadNotPossiblesPersec, + prometheus.GaugeValue, + float64(dst[0].FastReadNotPossiblesPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.FastReadResourceMissesPersec, + prometheus.GaugeValue, + float64(dst[0].FastReadResourceMissesPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.FastReadsPersec, + prometheus.GaugeValue, + float64(dst[0].FastReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.LazyWriteFlushesPersec, + prometheus.GaugeValue, + float64(dst[0].LazyWriteFlushesPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.LazyWritePagesPersec, + prometheus.GaugeValue, + float64(dst[0].LazyWritePagesPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.MDLReadHitsPercent, + prometheus.GaugeValue, + float64(dst[0].MDLReadHitsPercent), + ) + + ch <- prometheus.MustNewConstMetric( + c.MDLReadsPersec, + prometheus.GaugeValue, + float64(dst[0].MDLReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.PinReadHitsPercent, + prometheus.GaugeValue, + float64(dst[0].PinReadHitsPercent), + ) + + ch <- prometheus.MustNewConstMetric( + c.PinReadsPersec, + prometheus.GaugeValue, + float64(dst[0].PinReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.ReadAheadsPersec, + prometheus.GaugeValue, + float64(dst[0].ReadAheadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.SyncCopyReadsPersec, + prometheus.GaugeValue, + float64(dst[0].SyncCopyReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.SyncDataMapsPersec, + prometheus.GaugeValue, + float64(dst[0].SyncDataMapsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.SyncFastReadsPersec, + prometheus.GaugeValue, + float64(dst[0].SyncFastReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.SyncMDLReadsPersec, + prometheus.GaugeValue, + float64(dst[0].SyncMDLReadsPersec), + ) + + ch <- prometheus.MustNewConstMetric( + c.SyncPinReadsPersec, + prometheus.GaugeValue, + float64(dst[0].SyncPinReadsPersec), + ) + + return nil, nil +}