From 62dc9bfa7b554dbc54e225ad1daf9379fa1f0271 Mon Sep 17 00:00:00 2001 From: Mariana Dima Date: Thu, 25 Apr 2019 08:14:26 -0700 Subject: [PATCH] Assign object name from counter path when the instance name is not defined (#11878) * Assign object name from counter path when the instance name is not defined Fixes #6528 * Adressed review comments * Fix changelog entry --- CHANGELOG.next.asciidoc | 1 + .../perfmon/pdh_integration_windows_test.go | 32 +++++++++++++++++++ .../module/windows/perfmon/pdh_windows.go | 21 +++++++++--- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 390c2ece7d04..d42d9d672e4a 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -165,6 +165,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Allow module configurations to have variants {pull}9118[9118] - Add `timeseries.instance` field calculation. {pull}10293[10293] - Added new disk states and raid level to the system/raid metricset. {pull}11613[11613] +- Add check on object name in the counter path if the instance name is missing {issue}6528[6528] {pull}11878[11878] *Packetbeat* diff --git a/metricbeat/module/windows/perfmon/pdh_integration_windows_test.go b/metricbeat/module/windows/perfmon/pdh_integration_windows_test.go index 2656c579b2e9..74ea68614c4b 100644 --- a/metricbeat/module/windows/perfmon/pdh_integration_windows_test.go +++ b/metricbeat/module/windows/perfmon/pdh_integration_windows_test.go @@ -24,6 +24,8 @@ import ( "time" "unsafe" + "github.com/elastic/beats/libbeat/common" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" @@ -72,6 +74,36 @@ func TestData(t *testing.T) { mbtest.WriteEventToDataJSON(t, beatEvent, "") } +func TestCounterWithNoInstanceName(t *testing.T) { + config := map[string]interface{}{ + "module": "windows", + "metricsets": []string{"perfmon"}, + "perfmon.counters": []map[string]string{ + { + "instance_label": "processor.name", + "measurement_label": "processor.time.total.pct", + "query": `\UDPv4\Datagrams Sent/sec`, + }, + }, + } + + ms := mbtest.NewReportingMetricSetV2(t, config) + mbtest.ReportingFetchV2(ms) + time.Sleep(60 * time.Millisecond) + + events, errs := mbtest.ReportingFetchV2(ms) + if len(errs) > 0 { + t.Fatal(errs) + } + if len(events) == 0 { + t.Fatal("no events received") + } + process := events[0].MetricSetFields["processor"].(common.MapStr) + // Check values + assert.EqualValues(t, "UDPv4", process["name"]) + +} + func TestQuery(t *testing.T) { q, err := NewQuery("") if err != nil { diff --git a/metricbeat/module/windows/perfmon/pdh_windows.go b/metricbeat/module/windows/perfmon/pdh_windows.go index eb7554507312..a18e560dea43 100644 --- a/metricbeat/module/windows/perfmon/pdh_windows.go +++ b/metricbeat/module/windows/perfmon/pdh_windows.go @@ -52,6 +52,7 @@ var ( sizeofPdhCounterValueItem = (int)(unsafe.Sizeof(pdhCounterValueItem{})) wildcardRegexp = regexp.MustCompile(`.*\(\*\).*`) instanceNameRegexp = regexp.MustCompile(`.*\((.*)\).*`) + objectNameRegexp = regexp.MustCompile(`\\([^\\]+)\\`) ) type PdhQueryHandle uintptr @@ -247,13 +248,11 @@ func (q *Query) AddCounter(counterPath string, format Format, instanceName strin // Extract the instance name from the counterPath for non-wildcard paths. if !wildcard && instanceName == "" { - matches := instanceNameRegexp.FindStringSubmatch(counterPath) - if len(matches) != 2 { - return errors.New("query doesn't contain an instance name. In this case you have to define 'instance_name'") + instanceName, err = matchInstanceName(counterPath) + if err != nil { + return err } - instanceName = matches[1] } - q.counters[counterPath] = &Counter{ handle: h, instanceName: instanceName, @@ -268,6 +267,18 @@ func (q *Query) AddCounter(counterPath string, format Format, instanceName strin return nil } +// matchInstanceName will check first for instance and then for any objects names +func matchInstanceName(counterPath string) (string, error) { + matches := instanceNameRegexp.FindStringSubmatch(counterPath) + if len(matches) != 2 { + matches = objectNameRegexp.FindStringSubmatch(counterPath) + } + if len(matches) == 2 { + return matches[1], nil + } + return "", errors.New("query doesn't contain an instance name. In this case you have to define 'instance_name'") +} + func (q *Query) Execute() error { return PdhCollectQueryData(q.handle) }