mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 01:59:04 +02:00
wmi: add a multiplier option to convert values to base units (#2772)
Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
f6e8e67a00
commit
db1ad936dc
@@ -20,6 +20,7 @@ package wmi
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/internal/config/yamlstring"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/multiplier"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.yaml.in/yaml/v3"
|
||||
)
|
||||
@@ -48,16 +49,18 @@ type LabelProperty struct {
|
||||
}
|
||||
|
||||
type Property struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Metric string `json:"metric" yaml:"metric"`
|
||||
Help string `json:"help" yaml:"help"`
|
||||
Type string `json:"type" yaml:"type"`
|
||||
Labels map[string]string `json:"labels" yaml:"labels"`
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Metric string `json:"metric" yaml:"metric"`
|
||||
Help string `json:"help" yaml:"help"`
|
||||
Type string `json:"type" yaml:"type"`
|
||||
Labels map[string]string `json:"labels" yaml:"labels"`
|
||||
Multiplier *float64 `json:"multiplier" yaml:"multiplier"`
|
||||
|
||||
// Resolved at Build time.
|
||||
elementName mi.ElementName
|
||||
desc *prometheus.Desc
|
||||
metricType prometheus.ValueType
|
||||
multiplier multiplier.Multiplier
|
||||
}
|
||||
|
||||
// UnmarshalYAML decodes the wmi block of the configuration file, where the
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/labelcache"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/multiplier"
|
||||
"github.com/prometheus-community/windows_exporter/internal/scrapecache"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -346,6 +347,12 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if property.multiplier, err = multiplier.New(property.Multiplier); err != nil {
|
||||
errs = append(errs, fmt.Errorf("query %s: property %q: %w", query.Name, property.Name, err))
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if label, ok := firstCommonLabel(query.labelNames, property.Labels); ok {
|
||||
errs = append(errs, fmt.Errorf("query %s: property %q: constant label %q is already set by a label property", query.Name, property.Name, label))
|
||||
|
||||
@@ -588,7 +595,7 @@ func (c *Collector) collectQuery(ch chan<- prometheus.Metric, scrape *labelcache
|
||||
ch <- scrape.MustNewConstMetric(
|
||||
property.desc,
|
||||
property.metricType,
|
||||
value,
|
||||
property.multiplier.Apply(value),
|
||||
labelValues...,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -167,6 +167,21 @@ func TestCollectorMetrics(t *testing.T) {
|
||||
Class: "Win32_OperatingSystem",
|
||||
Properties: []wmi.Property{{Name: "Primary", Metric: "windows_wmi_test_shared", Labels: map[string]string{"query": "b"}}},
|
||||
},
|
||||
{
|
||||
// The multiplier converts units, e.g. milliseconds to seconds.
|
||||
Name: "scaled_down",
|
||||
Class: "Win32_OperatingSystem",
|
||||
Properties: []wmi.Property{
|
||||
{Name: "Primary", Metric: "windows_wmi_test_scaled", Labels: map[string]string{"query": "down"}, Multiplier: new(0.001)},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "scaled_up",
|
||||
Class: "Win32_OperatingSystem",
|
||||
Properties: []wmi.Property{
|
||||
{Name: "Primary", Metric: "windows_wmi_test_scaled", Labels: map[string]string{"query": "up"}, Multiplier: new(3600.0)},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "missing_class",
|
||||
Class: "Win32_WindowsExporterDoesNotExist",
|
||||
@@ -205,6 +220,8 @@ windows_wmi_query_success{query="kernel"} 1
|
||||
windows_wmi_query_success{query="missing_class"} 0
|
||||
windows_wmi_query_success{query="os"} 1
|
||||
windows_wmi_query_success{query="partial"} 0
|
||||
windows_wmi_query_success{query="scaled_down"} 1
|
||||
windows_wmi_query_success{query="scaled_up"} 1
|
||||
windows_wmi_query_success{query="shared_a"} 1
|
||||
windows_wmi_query_success{query="shared_b"} 1
|
||||
windows_wmi_query_success{query="unsupported_label"} 0
|
||||
@@ -212,6 +229,10 @@ windows_wmi_query_success{query="unsupported_label"} 0
|
||||
# TYPE windows_wmi_test_parent_pid counter
|
||||
windows_wmi_test_parent_pid{foo="bar",handle="0",path="",pid="0",process="System Idle Process"} 0
|
||||
windows_wmi_test_parent_pid{foo="bar",handle="4",path="",pid="4",process="System"} 0
|
||||
# HELP windows_wmi_test_scaled windows_exporter: custom WMI metric
|
||||
# TYPE windows_wmi_test_scaled gauge
|
||||
windows_wmi_test_scaled{query="down"} 0.001
|
||||
windows_wmi_test_scaled{query="up"} 3600
|
||||
# HELP windows_wmi_test_shared windows_exporter: custom WMI metric
|
||||
# TYPE windows_wmi_test_shared gauge
|
||||
windows_wmi_test_shared{query="a"} 1
|
||||
@@ -232,7 +253,7 @@ windows_wmi_test_shared{query="b"} 1
|
||||
|
||||
require.Equal(t, expected, strings.Join(lines, "\n"))
|
||||
|
||||
for _, name := range []string{"kernel", "missing_class", "os", "partial", "shared_a", "shared_b", "unsupported_label"} {
|
||||
for _, name := range []string{"kernel", "missing_class", "os", "partial", "scaled_down", "scaled_up", "shared_a", "shared_b", "unsupported_label"} {
|
||||
require.Regexp(t, `(?m)^windows_wmi_query_duration_seconds\{query="`+name+`"\} \d`, got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +190,16 @@ func TestCollectorBuildErrors(t *testing.T) {
|
||||
queries: valid(func(q *wmi.Query) { q.Properties[0].Type = "histogram" }),
|
||||
err: `invalid type "histogram"`,
|
||||
},
|
||||
{
|
||||
name: "zero multiplier",
|
||||
queries: valid(func(q *wmi.Query) { q.Properties[0].Multiplier = new(0.0) }),
|
||||
err: `property "FreeSpace": multiplier must be a positive finite number, got 0`,
|
||||
},
|
||||
{
|
||||
name: "negative multiplier",
|
||||
queries: valid(func(q *wmi.Query) { q.Properties[0].Multiplier = new(-1.0) }),
|
||||
err: `multiplier must be a positive finite number, got -1`,
|
||||
},
|
||||
{
|
||||
name: "invalid label property name",
|
||||
queries: valid(func(q *wmi.Query) { q.LabelProperties = []wmi.LabelProperty{{Name: ""}} }),
|
||||
|
||||
Reference in New Issue
Block a user