mirror of
https://github.com/prometheus-community/windows_exporter
synced 2025-01-19 13:51:23 +00:00
Merge pull request #461 from martinlindhe/specific-perflib-objects
Only query the perflib objects we need
This commit is contained in:
commit
b64ccbe683
@ -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
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["adfs"] = newADFSCollector
|
||||
registerCollector("adfs", newADFSCollector)
|
||||
}
|
||||
|
||||
type adfsCollector struct {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["container"] = NewContainerMetricsCollector
|
||||
registerCollector("container", NewContainerMetricsCollector)
|
||||
}
|
||||
|
||||
// A ContainerMetricsCollector is a Prometheus collector for containers metrics
|
||||
|
@ -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.
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["cs"] = NewCSCollector
|
||||
registerCollector("cs", NewCSCollector)
|
||||
}
|
||||
|
||||
// A CSCollector is a Prometheus collector for WMI metrics
|
||||
|
@ -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
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["hyperv"] = NewHyperVCollector
|
||||
registerCollector("hyperv", NewHyperVCollector)
|
||||
}
|
||||
|
||||
// HyperVCollector is a Prometheus collector for hyper-v
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["iis"] = NewIISCollector
|
||||
registerCollector("iis", NewIISCollector)
|
||||
}
|
||||
|
||||
type simple_version struct {
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["logical_disk"] = NewLogicalDiskCollector
|
||||
registerCollector("logical_disk", NewLogicalDiskCollector, "LogicalDisk")
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["logon"] = NewLogonCollector
|
||||
registerCollector("logon", NewLogonCollector)
|
||||
}
|
||||
|
||||
// A LogonCollector is a Prometheus collector for WMI metrics
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["memory"] = NewMemoryCollector
|
||||
registerCollector("memory", NewMemoryCollector, "Memory")
|
||||
}
|
||||
|
||||
// A MemoryCollector is a Prometheus collector for perflib Memory metrics
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["msmq"] = NewMSMQCollector
|
||||
registerCollector("msmq", NewMSMQCollector)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -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
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["net"] = NewNetworkCollector
|
||||
registerCollector("net", NewNetworkCollector, "Network Interface")
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["os"] = NewOSCollector
|
||||
registerCollector("os", NewOSCollector)
|
||||
}
|
||||
|
||||
// A OSCollector is a Prometheus collector for WMI metrics
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["process"] = NewProcessCollector
|
||||
registerCollector("process", NewProcessCollector)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["service"] = NewserviceCollector
|
||||
registerCollector("service", NewserviceCollector)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Factories["system"] = NewSystemCollector
|
||||
registerCollector("system", NewSystemCollector, "System")
|
||||
}
|
||||
|
||||
// A SystemCollector is a Prometheus collector for WMI metrics
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
31
exporter.go
31
exporter.go
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user