Skip to content

Commit 818b8d5

Browse files
braydonkdehaansa
andauthored
vendor perflib in perfcounterscraper (#38859)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description This PR vendors the `perflib` package from the latest commit of [`windows_exporter`](https://github.com/prometheus-community/windows_exporter). Some constants had to be copied from related packages in `windows_exporter` to make it work. Original license attribution to Prometheus Authors under MIT license is included in this copy. <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue #38858 <!--Describe what testing was performed and which tests were added.--> #### Testing Ran tests locally, running integration tests in CI. <!--Describe the documentation added.--> #### Documentation <!--Please delete paragraphs that you did not use before submitting.--> --------- Co-authored-by: Sam DeHaan <[email protected]>
1 parent 3f160ea commit 818b8d5

File tree

19 files changed

+1103
-24
lines changed

19 files changed

+1103
-24
lines changed

connector/datadogconnector/go.sum

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporter/datadogexporter/go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,6 @@ require (
354354
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
355355
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
356356
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
357-
github.com/prometheus-community/windows_exporter v0.27.2 // indirect
358357
github.com/prometheus/alertmanager v0.27.0 // indirect
359358
github.com/prometheus/client_golang v1.21.1 // indirect
360359
github.com/prometheus/client_model v0.6.1 // indirect

exporter/datadogexporter/go.sum

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporter/datadogexporter/integrationtest/go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,6 @@ require (
323323
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
324324
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
325325
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
326-
github.com/prometheus-community/windows_exporter v0.27.2 // indirect
327326
github.com/prometheus/alertmanager v0.27.0 // indirect
328327
github.com/prometheus/client_golang v1.21.1 // indirect
329328
github.com/prometheus/client_model v0.6.1 // indirect

exporter/datadogexporter/integrationtest/go.sum

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/hostmetricsreceiver/go.mod

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ require (
88
github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.123.0
99
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata v0.123.0
1010
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.123.0
11-
github.com/prometheus-community/windows_exporter v0.27.2
1211
github.com/prometheus/procfs v0.16.0
1312
github.com/shirou/gopsutil/v4 v4.25.3
1413
github.com/stretchr/testify v1.10.0
@@ -51,8 +50,6 @@ require (
5150
github.com/docker/go-units v0.5.0 // indirect
5251
github.com/ebitengine/purego v0.8.2 // indirect
5352
github.com/felixge/httpsnoop v1.0.4 // indirect
54-
github.com/go-kit/log v0.2.1 // indirect
55-
github.com/go-logfmt/logfmt v0.5.1 // indirect
5653
github.com/go-logr/logr v1.4.2 // indirect
5754
github.com/go-logr/stdr v1.2.2 // indirect
5855
github.com/go-ole/go-ole v1.3.0 // indirect
@@ -63,7 +60,7 @@ require (
6360
github.com/hashicorp/go-version v1.7.0 // indirect
6461
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
6562
github.com/json-iterator/go v1.1.12 // indirect
66-
github.com/klauspost/compress v1.17.11 // indirect
63+
github.com/klauspost/compress v1.18.0 // indirect
6764
github.com/knadh/koanf/maps v0.1.2 // indirect
6865
github.com/knadh/koanf/providers/confmap v0.1.0 // indirect
6966
github.com/knadh/koanf/v2 v2.1.2 // indirect

receiver/hostmetricsreceiver/go.sum

Lines changed: 2 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/hostmetricsreceiver/internal/perfcounters/doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
// Package perfcounters is a thin wrapper around
4+
// Package perfcounters is a thin wrapper around code vendored from
55
// https://pkg.go.dev/github.com/prometheus-community/windows_exporter/pkg/perflib that
66
// provides functions to scrape raw performance counter data, without
77
// calculating rates or formatting them, from the registry.

receiver/hostmetricsreceiver/internal/perfcounters/perfcounter_scraper.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import (
1010
"strconv"
1111
"strings"
1212

13-
"github.com/prometheus-community/windows_exporter/pkg/perflib"
14-
1513
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/filterset"
14+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/perfcounters/third_party/perflib"
1615
)
1716

1817
const totalInstanceName = "_Total"
@@ -67,7 +66,7 @@ func (p *PerfLibScraper) Initialize(objects ...string) error {
6766
}
6867

6968
func (p *PerfLibScraper) Scrape() (PerfDataCollection, error) {
70-
objects, err := perflib.QueryPerformanceData(p.objectIndices)
69+
objects, err := perflib.QueryPerformanceData(p.objectIndices, "")
7170
if err != nil {
7271
return nil, fmt.Errorf("failed to query performance data: %w", err)
7372
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2018 Leopold Schabel / The perflib_exporter authors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
//go:build windows
2+
3+
package perflib // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/perfcounters/third_party/perflib"
4+
5+
import (
6+
"fmt"
7+
"reflect"
8+
"strings"
9+
)
10+
11+
type Collector struct {
12+
object string
13+
query string
14+
15+
counters map[string]Counter
16+
nameIndexValue int
17+
}
18+
19+
type Counter struct {
20+
Name string
21+
Desc string
22+
Instances map[string]uint32
23+
Type uint32
24+
Frequency float64
25+
26+
FieldIndexValue int
27+
FieldIndexSecondValue int
28+
}
29+
30+
func NewCollector[T any](object string, _ []string) (*Collector, error) {
31+
collector := &Collector{
32+
object: object,
33+
query: MapCounterToIndex(object),
34+
nameIndexValue: -1,
35+
counters: make(map[string]Counter),
36+
}
37+
38+
var values [0]T
39+
valueType := reflect.TypeOf(values).Elem()
40+
41+
if f, ok := valueType.FieldByName("Name"); ok {
42+
if f.Type.Kind() == reflect.String {
43+
collector.nameIndexValue = f.Index[0]
44+
}
45+
}
46+
47+
for _, f := range reflect.VisibleFields(valueType) {
48+
counterName, ok := f.Tag.Lookup("perfdata")
49+
if !ok {
50+
continue
51+
}
52+
53+
var counter Counter
54+
if counter, ok = collector.counters[counterName]; !ok {
55+
counter = Counter{
56+
Name: counterName,
57+
FieldIndexSecondValue: -1,
58+
FieldIndexValue: -1,
59+
}
60+
}
61+
62+
if strings.HasSuffix(counterName, ",secondvalue") {
63+
counterName = strings.TrimSuffix(counterName, ",secondvalue")
64+
65+
counter.FieldIndexSecondValue = f.Index[0]
66+
} else {
67+
counter.FieldIndexValue = f.Index[0]
68+
}
69+
70+
collector.counters[counterName] = counter
71+
}
72+
73+
var collectValues []T
74+
75+
if err := collector.Collect(&collectValues); err != nil {
76+
return nil, fmt.Errorf("failed to collect initial data: %w", err)
77+
}
78+
79+
return collector, nil
80+
}
81+
82+
func (c *Collector) Describe() map[string]string {
83+
return map[string]string{}
84+
}
85+
86+
func (c *Collector) Collect(data any) error {
87+
dv := reflect.ValueOf(data)
88+
if dv.Kind() != reflect.Ptr || dv.IsNil() {
89+
return ErrInvalidEntityType
90+
}
91+
92+
dv = dv.Elem()
93+
94+
elemType := dv.Type().Elem()
95+
elemValue := reflect.ValueOf(reflect.New(elemType).Interface()).Elem()
96+
97+
if dv.Kind() != reflect.Slice || elemType.Kind() != reflect.Struct {
98+
return ErrInvalidEntityType
99+
}
100+
101+
perfObjects, err := QueryPerformanceData(c.query, c.object)
102+
if err != nil {
103+
return fmt.Errorf("QueryPerformanceData: %w", err)
104+
}
105+
106+
if len(perfObjects) == 0 || perfObjects[0] == nil || len(perfObjects[0].Instances) == 0 {
107+
return nil
108+
}
109+
110+
if dv.Len() != 0 {
111+
dv.Set(reflect.MakeSlice(dv.Type(), 0, len(perfObjects[0].Instances)))
112+
}
113+
114+
dv.Clear()
115+
116+
for _, perfObject := range perfObjects {
117+
if perfObject.Name != c.object {
118+
continue
119+
}
120+
121+
for _, perfInstance := range perfObject.Instances {
122+
instanceName := perfInstance.Name
123+
if strings.HasSuffix(instanceName, "_Total") {
124+
continue
125+
}
126+
127+
if instanceName == "" || instanceName == "*" {
128+
instanceName = InstanceEmpty
129+
}
130+
131+
if c.nameIndexValue != -1 {
132+
elemValue.Field(c.nameIndexValue).SetString(instanceName)
133+
}
134+
135+
dv.Set(reflect.Append(dv, elemValue))
136+
index := dv.Len() - 1
137+
138+
for _, perfCounter := range perfInstance.Counters {
139+
if perfCounter.Def.IsBaseValue && !perfCounter.Def.IsNanosecondCounter {
140+
continue
141+
}
142+
143+
counter, ok := c.counters[perfCounter.Def.Name]
144+
if !ok {
145+
continue
146+
}
147+
148+
switch perfCounter.Def.CounterType {
149+
case PERF_ELAPSED_TIME:
150+
dv.Index(index).
151+
Field(counter.FieldIndexValue).
152+
SetFloat(float64((perfCounter.Value - WindowsEpoch) / perfObject.Frequency))
153+
case PERF_100NSEC_TIMER, PERF_PRECISION_100NS_TIMER:
154+
dv.Index(index).
155+
Field(counter.FieldIndexValue).
156+
SetFloat(float64(perfCounter.Value) * TicksToSecondScaleFactor)
157+
default:
158+
if counter.FieldIndexSecondValue != -1 {
159+
dv.Index(index).
160+
Field(counter.FieldIndexSecondValue).
161+
SetFloat(float64(perfCounter.SecondValue))
162+
}
163+
164+
if counter.FieldIndexValue != -1 {
165+
dv.Index(index).
166+
Field(counter.FieldIndexValue).
167+
SetFloat(float64(perfCounter.Value))
168+
}
169+
}
170+
}
171+
}
172+
}
173+
174+
return nil
175+
}
176+
177+
func (c *Collector) Close() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//go:build windows
2+
3+
package perflib // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/perfcounters/third_party/perflib"
4+
5+
import "errors"
6+
7+
var ErrInvalidEntityType = errors.New("invalid entity type")

0 commit comments

Comments
 (0)