Don't fail when a perflib counter isn't found

This commit is contained in:
Calle Pettersson
2019-08-03 13:15:45 +02:00
parent 0ecf3cd792
commit 9308108284
4 changed files with 39 additions and 36 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ VERSION
*.swp *.swp
*.un~ *.un~
output/ output/
.idea

View File

@@ -1,8 +1,12 @@
package collector package collector
import ( import (
"strconv"
"github.com/leoluk/perflib_exporter/perflib" "github.com/leoluk/perflib_exporter/perflib"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
"golang.org/x/sys/windows/registry"
) )
// ... // ...
@@ -15,6 +19,34 @@ const (
windowsEpoch = 116444736000000000 windowsEpoch = 116444736000000000
) )
// getWindowsVersion reads the version number of the OS from the Registry
// See https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version
func getWindowsVersion() float64 {
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
if err != nil {
log.Warn("Couldn't open registry", err)
return 0
}
defer func() {
err = k.Close()
if err != nil {
log.Warnf("Failed to close registry key: %v", err)
}
}()
currentv, _, err := k.GetStringValue("CurrentVersion")
if err != nil {
log.Warn("Couldn't open registry to determine current Windows version:", err)
return 0
}
currentv_flt, err := strconv.ParseFloat(currentv, 64)
log.Debugf("Detected Windows version %f\n", currentv_flt)
return currentv_flt
}
// Factories ... // Factories ...
var Factories = make(map[string]func() (Collector, error)) var Factories = make(map[string]func() (Collector, error))

View File

@@ -3,46 +3,15 @@
package collector package collector
import ( import (
"strconv"
"strings" "strings"
"golang.org/x/sys/windows/registry"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
) )
func init() { func init() {
Factories["cpu"] = newCPUCollector Factories["cpu"] = newCPUCollector
} }
// A function to get Windows version from registry
func getWindowsVersion() float64 {
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
if err != nil {
log.Warn("Couldn't open registry", err)
return 0
}
defer func() {
err = k.Close()
if err != nil {
log.Warnf("Failed to close registry key: %v", err)
}
}()
currentv, _, err := k.GetStringValue("CurrentVersion")
if err != nil {
log.Warn("Couldn't open registry to determine current Windows version:", err)
return 0
}
currentv_flt, err := strconv.ParseFloat(currentv, 64)
log.Debugf("Detected Windows version %f\n", currentv_flt)
return currentv_flt
}
type cpuCollectorBasic struct { type cpuCollectorBasic struct {
CStateSecondsTotal *prometheus.Desc CStateSecondsTotal *prometheus.Desc
TimeTotal *prometheus.Desc TimeTotal *prometheus.Desc
@@ -67,10 +36,12 @@ func newCPUCollector() (Collector, error) {
const subsystem = "cpu" const subsystem = "cpu"
version := getWindowsVersion() version := getWindowsVersion()
// Windows version by number https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version // For Windows 2008 (version 6.0) or earlier we only have the "Processor"
// For Windows 2008 or earlier Windows version is 6.0 or lower, where we only have the older "Processor" counters // class. As of Windows 2008 R2 (version 6.1) the more detailed
// For Windows 2008 R2 or later Windows version is 6.1 or higher, so we can use "ProcessorInformation" counters // "ProcessorInformation" set is available (although some of the counters
// Value 6.05 was selected just to split between Windows versions // 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.
if version < 6.05 { if version < 6.05 {
return &cpuCollectorBasic{ return &cpuCollectorBasic{
CStateSecondsTotal: prometheus.NewDesc( CStateSecondsTotal: prometheus.NewDesc(

View File

@@ -64,7 +64,6 @@ func unmarshalObject(obj *perflib.PerfObject, vs interface{}) error {
ctr, found := counters[tag] ctr, found := counters[tag]
if !found { if !found {
log.Debugf("missing counter %q, has %v", tag, counters) log.Debugf("missing counter %q, has %v", tag, counters)
return fmt.Errorf("could not find counter %q on instance", tag)
} }
if !target.Field(i).CanSet() { if !target.Field(i).CanSet() {
return fmt.Errorf("tagged field %v cannot be written to", f) return fmt.Errorf("tagged field %v cannot be written to", f)