Merge pull request #461 from martinlindhe/specific-perflib-objects

Only query the perflib objects we need
This commit is contained in:
Calle Pettersson 2020-03-01 12:55:03 +01:00 committed by GitHub
commit b64ccbe683
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 97 additions and 57 deletions

View File

@ -11,7 +11,7 @@ import (
)
func init() {
Factories["ad"] = NewADCollector
registerCollector("ad", NewADCollector)
}
// A ADCollector is a Prometheus collector for WMI Win32_PerfRawData_DirectoryServices_DirectoryServices metrics

View File

@ -7,7 +7,7 @@ import (
)
func init() {
Factories["adfs"] = newADFSCollector
registerCollector("adfs", newADFSCollector)
}
type adfsCollector struct {

View File

@ -2,6 +2,7 @@ package collector
import (
"strconv"
"strings"
"github.com/leoluk/perflib_exporter/perflib"
"github.com/prometheus/client_golang/prometheus"
@ -47,8 +48,41 @@ func getWindowsVersion() float64 {
return currentv_flt
}
// Factories ...
var Factories = make(map[string]func() (Collector, error))
type collectorBuilder func() (Collector, error)
var (
builders = make(map[string]collectorBuilder)
perfCounterDependencies = make(map[string]string)
)
func registerCollector(name string, builder collectorBuilder, perfCounterNames ...string) {
builders[name] = builder
perfIndicies := make([]string, 0, len(perfCounterNames))
for _, cn := range perfCounterNames {
perfIndicies = append(perfIndicies, MapCounterToIndex(cn))
}
perfCounterDependencies[name] = strings.Join(perfIndicies, " ")
}
func Available() []string {
cs := make([]string, 0, len(builders))
for c := range builders {
cs = append(cs, c)
}
return cs
}
func Build(collector string) (Collector, error) {
return builders[collector]()
}
func getPerfQuery(collectors []string) string {
parts := make([]string, 0, len(collectors))
for _, c := range collectors {
if p := perfCounterDependencies[c]; p != "" {
parts = append(parts, p)
}
}
return strings.Join(parts, " ")
}
// Collector is the interface a collector has to implement.
type Collector interface {
@ -61,8 +95,9 @@ type ScrapeContext struct {
}
// PrepareScrapeContext creates a ScrapeContext to be used during a single scrape
func PrepareScrapeContext() (*ScrapeContext, error) {
objs, err := getPerflibSnapshot()
func PrepareScrapeContext(collectors []string) (*ScrapeContext, error) {
q := getPerfQuery(collectors) // TODO: Memoize
objs, err := getPerflibSnapshot(q)
if err != nil {
return nil, err
}

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["container"] = NewContainerMetricsCollector
registerCollector("container", NewContainerMetricsCollector)
}
// A ContainerMetricsCollector is a Prometheus collector for containers metrics

View File

@ -9,7 +9,14 @@ import (
)
func init() {
Factories["cpu"] = newCPUCollector
var deps string
// See below for 6.05 magic value
if getWindowsVersion() > 6.05 {
deps = "Processor Information"
} else {
deps = "Processor"
}
registerCollector("cpu", newCPUCollector, deps)
}
type cpuCollectorBasic struct {
@ -38,7 +45,7 @@ func newCPUCollector() (Collector, error) {
version := getWindowsVersion()
// For Windows 2008 (version 6.0) or earlier we only have the "Processor"
// class. As of Windows 2008 R2 (version 6.1) the more detailed
// "ProcessorInformation" set is available (although some of the counters
// "Processor Information" set is available (although some of the counters
// are added in later versions, so we aren't guaranteed to get all of
// them).
// Value 6.05 was selected to split between Windows versions.

View File

@ -11,7 +11,7 @@ import (
)
func init() {
Factories["cs"] = NewCSCollector
registerCollector("cs", NewCSCollector)
}
// A CSCollector is a Prometheus collector for WMI metrics

View File

@ -11,7 +11,7 @@ import (
)
func init() {
Factories["dns"] = NewDNSCollector
registerCollector("dns", NewDNSCollector)
}
// A DNSCollector is a Prometheus collector for WMI Win32_PerfRawData_DNS_DNS metrics

View File

@ -11,7 +11,7 @@ import (
)
func init() {
Factories["hyperv"] = NewHyperVCollector
registerCollector("hyperv", NewHyperVCollector)
}
// HyperVCollector is a Prometheus collector for hyper-v

View File

@ -16,7 +16,7 @@ import (
)
func init() {
Factories["iis"] = NewIISCollector
registerCollector("iis", NewIISCollector)
}
type simple_version struct {

View File

@ -12,7 +12,7 @@ import (
)
func init() {
Factories["logical_disk"] = NewLogicalDiskCollector
registerCollector("logical_disk", NewLogicalDiskCollector, "LogicalDisk")
}
var (

View File

@ -11,7 +11,7 @@ import (
)
func init() {
Factories["logon"] = NewLogonCollector
registerCollector("logon", NewLogonCollector)
}
// A LogonCollector is a Prometheus collector for WMI metrics

View File

@ -11,7 +11,7 @@ import (
)
func init() {
Factories["memory"] = NewMemoryCollector
registerCollector("memory", NewMemoryCollector, "Memory")
}
// A MemoryCollector is a Prometheus collector for perflib Memory metrics

View File

@ -12,7 +12,7 @@ import (
)
func init() {
Factories["msmq"] = NewMSMQCollector
registerCollector("msmq", NewMSMQCollector)
}
var (

View File

@ -127,7 +127,7 @@ func mssqlExpandEnabledCollectors(enabled string) []string {
}
func init() {
Factories["mssql"] = NewMSSQLCollector
registerCollector("mssql", NewMSSQLCollector)
}
// A MSSQLCollector is a Prometheus collector for various WMI Win32_PerfRawData_MSSQLSERVER_* metrics

View File

@ -12,7 +12,7 @@ import (
)
func init() {
Factories["net"] = NewNetworkCollector
registerCollector("net", NewNetworkCollector, "Network Interface")
}
var (

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrexceptions"] = NewNETFramework_NETCLRExceptionsCollector
registerCollector("netframework_clrexceptions", NewNETFramework_NETCLRExceptionsCollector)
}
// A NETFramework_NETCLRExceptionsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRExceptions metrics

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrinterop"] = NewNETFramework_NETCLRInteropCollector
registerCollector("netframework_clrinterop", NewNETFramework_NETCLRInteropCollector)
}
// A NETFramework_NETCLRInteropCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRInterop metrics

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrjit"] = NewNETFramework_NETCLRJitCollector
registerCollector("netframework_clrjit", NewNETFramework_NETCLRJitCollector)
}
// A NETFramework_NETCLRJitCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRJit metrics

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrloading"] = NewNETFramework_NETCLRLoadingCollector
registerCollector("netframework_clrloading", NewNETFramework_NETCLRLoadingCollector)
}
// A NETFramework_NETCLRLoadingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLoading metrics

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrlocksandthreads"] = NewNETFramework_NETCLRLocksAndThreadsCollector
registerCollector("netframework_clrlocksandthreads", NewNETFramework_NETCLRLocksAndThreadsCollector)
}
// A NETFramework_NETCLRLocksAndThreadsCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads metrics

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrmemory"] = NewNETFramework_NETCLRMemoryCollector
registerCollector("netframework_clrmemory", NewNETFramework_NETCLRMemoryCollector)
}
// A NETFramework_NETCLRMemoryCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRMemory metrics

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrremoting"] = NewNETFramework_NETCLRRemotingCollector
registerCollector("netframework_clrremoting", NewNETFramework_NETCLRRemotingCollector)
}
// A NETFramework_NETCLRRemotingCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRRemoting metrics

View File

@ -9,7 +9,7 @@ import (
)
func init() {
Factories["netframework_clrsecurity"] = NewNETFramework_NETCLRSecurityCollector
registerCollector("netframework_clrsecurity", NewNETFramework_NETCLRSecurityCollector)
}
// A NETFramework_NETCLRSecurityCollector is a Prometheus collector for WMI Win32_PerfRawData_NETFramework_NETCLRSecurity metrics

View File

@ -12,7 +12,7 @@ import (
)
func init() {
Factories["os"] = NewOSCollector
registerCollector("os", NewOSCollector)
}
// A OSCollector is a Prometheus collector for WMI metrics

View File

@ -3,14 +3,21 @@ package collector
import (
"fmt"
"reflect"
"strconv"
perflibCollector "github.com/leoluk/perflib_exporter/collector"
"github.com/leoluk/perflib_exporter/perflib"
"github.com/prometheus/common/log"
)
func getPerflibSnapshot() (map[string]*perflib.PerfObject, error) {
objects, err := perflib.QueryPerformanceData("Global")
var nametable = perflib.QueryNameTable("Counter 009") // Reads the names in English TODO: validate that the English names are always present
func MapCounterToIndex(name string) string {
return strconv.Itoa(int(nametable.LookupIndex(name)))
}
func getPerflibSnapshot(objNames string) (map[string]*perflib.PerfObject, error) {
objects, err := perflib.QueryPerformanceData(objNames)
if err != nil {
return nil, err
}

View File

@ -13,7 +13,7 @@ import (
)
func init() {
Factories["process"] = NewProcessCollector
registerCollector("process", NewProcessCollector)
}
var (

View File

@ -12,7 +12,7 @@ import (
)
func init() {
Factories["service"] = NewserviceCollector
registerCollector("service", NewserviceCollector)
}
var (

View File

@ -8,7 +8,7 @@ import (
)
func init() {
Factories["system"] = NewSystemCollector
registerCollector("system", NewSystemCollector, "System")
}
// A SystemCollector is a Prometheus collector for WMI metrics

View File

@ -10,7 +10,7 @@ import (
)
func init() {
Factories["tcp"] = NewTCPCollector
registerCollector("tcp", NewTCPCollector)
}
// A TCPCollector is a Prometheus collector for WMI Win32_PerfRawData_Tcpip_TCPv4 metrics

View File

@ -54,7 +54,7 @@ type textFileCollector struct {
}
func init() {
Factories["textfile"] = NewTextFileCollector
registerCollector("textfile", NewTextFileCollector)
}
// NewTextFileCollector returns a new Collector exposing metrics read from files

View File

@ -7,7 +7,7 @@ import (
)
func init() {
Factories["thermalzone"] = NewThermalZoneCollector
registerCollector("thermalzone", NewThermalZoneCollector)
}
// A thermalZoneCollector is a Prometheus collector for WMI Win32_PerfRawData_Counters_ThermalZoneInformation metrics

View File

@ -11,7 +11,7 @@ import (
)
func init() {
Factories["vmware"] = NewVmwareCollector
registerCollector("vmware", NewVmwareCollector)
}
// A VmwareCollector is a Prometheus collector for WMI Win32_PerfRawData_vmGuestLib_VMem/Win32_PerfRawData_vmGuestLib_VCPU metrics

View File

@ -97,7 +97,11 @@ func (coll WmiCollector) Collect(ch chan<- prometheus.Metric) {
)
t := time.Now()
scrapeContext, err := collector.PrepareScrapeContext()
cs := make([]string, 0, len(coll.collectors))
for name := range coll.collectors {
cs = append(cs, name)
}
scrapeContext, err := collector.PrepareScrapeContext(cs)
ch <- prometheus.MustNewConstMetric(
snapshotDuration,
prometheus.GaugeValue,
@ -188,17 +192,6 @@ func (coll WmiCollector) Collect(ch chan<- prometheus.Metric) {
l.Unlock()
}
func filterAvailableCollectors(collectors string) string {
var availableCollectors []string
for _, c := range strings.Split(collectors, ",") {
_, ok := collector.Factories[c]
if ok {
availableCollectors = append(availableCollectors, c)
}
}
return strings.Join(availableCollectors, ",")
}
func execute(name string, c collector.Collector, ctx *collector.ScrapeContext, ch chan<- prometheus.Metric) collectorOutcome {
t := time.Now()
err := c.Collect(ctx, ch)
@ -239,16 +232,13 @@ func loadCollectors(list string) (map[string]collector.Collector, error) {
enabled := expandEnabledCollectors(list)
for _, name := range enabled {
fn, ok := collector.Factories[name]
if !ok {
return nil, fmt.Errorf("collector '%s' not available", name)
}
c, err := fn()
c, err := collector.Build(name)
if err != nil {
return nil, err
}
collectors[name] = c
}
return collectors, nil
}
@ -278,7 +268,7 @@ func main() {
enabledCollectors = kingpin.Flag(
"collectors.enabled",
"Comma-separated list of collectors to use. Use '[defaults]' as a placeholder for all the collectors enabled by default.").
Default(filterAvailableCollectors(defaultCollectors)).String()
Default(defaultCollectors).String()
printCollectors = kingpin.Flag(
"collectors.print",
"If true, print available collectors and exit.",
@ -295,8 +285,9 @@ func main() {
kingpin.Parse()
if *printCollectors {
collectorNames := make(sort.StringSlice, 0, len(collector.Factories))
for n := range collector.Factories {
collectors := collector.Available()
collectorNames := make(sort.StringSlice, 0, len(collectors))
for _, n := range collectors {
collectorNames = append(collectorNames, n)
}
collectorNames.Sort()