diff --git a/internal/perfdata/v1/collector.go b/internal/perfdata/v1/collector.go index 36852236..5e0ee686 100644 --- a/internal/perfdata/v1/collector.go +++ b/internal/perfdata/v1/collector.go @@ -39,7 +39,7 @@ func (c *Collector) Describe() map[string]string { } func (c *Collector) Collect() (map[string]map[string]perftypes.CounterValues, error) { - perfObjects, err := QueryPerformanceData(c.query) + perfObjects, err := QueryPerformanceData(c.query, c.object) if err != nil { return nil, fmt.Errorf("QueryPerformanceData: %w", err) } diff --git a/internal/perfdata/v1/perflib.go b/internal/perfdata/v1/perflib.go index 6f3a322d..010f0d82 100644 --- a/internal/perfdata/v1/perflib.go +++ b/internal/perfdata/v1/perflib.go @@ -272,7 +272,7 @@ The query can be any of the following: Many objects have dependencies - if you query one of them, you often get back more than you asked for. */ -func QueryPerformanceData(query string) ([]*PerfObject, error) { +func QueryPerformanceData(query string, counterName string) ([]*PerfObject, error) { buffer, err := queryRawData(query) if err != nil { return nil, err @@ -297,6 +297,8 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) { // Parse the performance data numObjects := int(header.NumObjectTypes) + numFilteredObjects := 0 + objects := make([]*PerfObject, numObjects) objOffset := int64(header.HeaderLength) @@ -314,6 +316,14 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) { return nil, err } + perfCounterName := obj.LookupName() + + if counterName != "" && perfCounterName != counterName { + objOffset += int64(obj.TotalByteLength) + + continue + } + numCounterDefs := int(obj.NumCounters) numInstances := int(obj.NumInstances) @@ -328,7 +338,7 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) { counterDefs := make([]*PerfCounterDef, numCounterDefs) objects[i] = &PerfObject{ - Name: obj.LookupName(), + Name: perfCounterName, NameIndex: uint(obj.ObjectNameTitleIndex), Instances: instances, CounterDefs: counterDefs, @@ -410,9 +420,10 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) { // Next perfObjectType objOffset += int64(obj.TotalByteLength) + numFilteredObjects++ } - return objects, nil + return objects[:numFilteredObjects], nil } func parseCounterBlock(b []byte, r io.ReadSeeker, pos int64, defs []*PerfCounterDef) (int64, []*PerfCounter, error) { diff --git a/internal/perfdata/v1/perflib_test.go b/internal/perfdata/v1/perflib_test.go index 719172b5..10216fd3 100644 --- a/internal/perfdata/v1/perflib_test.go +++ b/internal/perfdata/v1/perflib_test.go @@ -6,6 +6,6 @@ import ( func BenchmarkQueryPerformanceData(b *testing.B) { for n := 0; n < b.N; n++ { - _, _ = QueryPerformanceData("Global") + _, _ = QueryPerformanceData("Global", "") } } diff --git a/internal/perfdata/v1/utils.go b/internal/perfdata/v1/utils.go index acb3aa8a..206841ae 100644 --- a/internal/perfdata/v1/utils.go +++ b/internal/perfdata/v1/utils.go @@ -9,7 +9,7 @@ func MapCounterToIndex(name string) string { } func GetPerflibSnapshot(objNames string) (map[string]*PerfObject, error) { - objects, err := QueryPerformanceData(objNames) + objects, err := QueryPerformanceData(objNames, "") if err != nil { return nil, err }