diff --git a/.chloggen/add-raw-value-scrape-to-winperfcounters.yaml b/.chloggen/add-raw-value-scrape-to-winperfcounters.yaml new file mode 100644 index 0000000000000..69991a8b63608 --- /dev/null +++ b/.chloggen/add-raw-value-scrape-to-winperfcounters.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: pkg/winperfcounters + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add methods to scrape raw values from Windows performance counters. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [39835] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [api] diff --git a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh.go b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh.go index d7ec07fc584ee..8dc974fb75eca 100644 --- a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh.go +++ b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh.go @@ -180,6 +180,8 @@ var ( pdh_ValidatePathW *syscall.Proc pdh_ExpandWildCardPathW *syscall.Proc pdh_GetCounterInfoW *syscall.Proc + pdh_GetRawCounterValue *syscall.Proc + pdh_GetRawCounterArrayW *syscall.Proc ) func init() { @@ -198,6 +200,8 @@ func init() { pdh_ValidatePathW = libpdhDll.MustFindProc("PdhValidatePathW") pdh_ExpandWildCardPathW = libpdhDll.MustFindProc("PdhExpandWildCardPathW") pdh_GetCounterInfoW = libpdhDll.MustFindProc("PdhGetCounterInfoW") + pdh_GetRawCounterValue = libpdhDll.MustFindProc("PdhGetRawCounterValue") + pdh_GetRawCounterArrayW = libpdhDll.MustFindProc("PdhGetRawCounterArrayW") } // PdhAddCounter adds the specified counter to the query. This is the internationalized version. Preferably, use the @@ -498,3 +502,45 @@ func PdhGetCounterInfo(hCounter PDH_HCOUNTER, bRetrieveExplainText int, pdwBuffe return uint32(ret) } + +// PdhGetRawCounterValue retrieves the current raw value of the specified counter. +// hCounter [in] +// Handle of the counter from which you want to retrieve the raw value. The PdhAddCounter function returns this handle. +// +// lpdwType [out] +// Pointer to a variable that receives the counter type. For a list of counter types, see the Counter Types section of the Windows Server documentation. +// +// pValue [out] +// Pointer to a PDH_RAW_COUNTER structure that receives the raw counter value. +func PdhGetRawCounterValue(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_RAW_COUNTER) uint32 { + ret, _, _ := pdh_GetRawCounterValue.Call( + uintptr(hCounter), + uintptr(unsafe.Pointer(lpdwType)), + uintptr(unsafe.Pointer(pValue)), + ) + + return uint32(ret) +} + +// PdhGetRawCounterArrayW retrieves an array of raw counter values for all instances of the specified counter. +// hCounter [in] +// Handle of the counter from which you want to retrieve the raw values. The PdhAddCounter function returns this handle. +// +// lpdwBufferSize [in, out] +// Pointer to a variable that specifies the size of the buffer, in bytes. If the buffer is too small, the function sets this variable to the required buffer size. +// +// lpdwBufferCount [out] +// Pointer to a variable that receives the number of elements in the buffer. +// +// itemBuffer [out] +// Pointer to a buffer that receives an array of PDH_RAW_COUNTER_ITEM structures. Each structure contains the raw counter value for an instance. +func PdhGetRawCounterArrayW(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *byte) uint32 { + ret, _, _ := pdh_GetRawCounterArrayW.Call( + uintptr(hCounter), + uintptr(unsafe.Pointer(lpdwBufferSize)), + uintptr(unsafe.Pointer(lpdwBufferCount)), + uintptr(unsafe.Pointer(itemBuffer)), + ) + + return uint32(ret) +} diff --git a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_386.go b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_386.go index 7a2339d11f15e..5e8951d07b039 100644 --- a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_386.go +++ b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_386.go @@ -73,6 +73,24 @@ type PDH_FMT_COUNTERVALUE_ITEM_LONG struct { FmtValue PDH_FMT_COUNTERVALUE_LONG } +// PDH_RAW_COUNTER structure contains the raw data value of a counter. +type PDH_RAW_COUNTER struct { + CStatus uint32 // Counter status that indicates if the counter value is valid. + padding [4]byte + TimeStamp FILETIME // Time at which the sample was taken. + FirstValue int64 // First raw counter value. + SecondValue int64 // Second raw counter value (used for some calculations). + MultiCount uint32 // Counter type-specific value. + padding2 [4]byte +} + +// PDH_RAW_COUNTER_ITEM structure contains the raw counter value for a specific instance. +type PDH_RAW_COUNTER_ITEM struct { + SzName *uint16 // Pointer to the instance name. + padding [4]byte + RawValue PDH_RAW_COUNTER // Raw counter value for the instance. +} + // PDH_COUNTER_INFO structure contains information describing the properties of a counter. This information also includes the counter path. type PDH_COUNTER_INFO struct { // Size of the structure, including the appended strings, in bytes. diff --git a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_amd64.go b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_amd64.go index 30c64b3d71e96..c6f7c521c4585 100644 --- a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_amd64.go +++ b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/pdh_amd64.go @@ -68,6 +68,21 @@ type PDH_FMT_COUNTERVALUE_ITEM_LONG struct { FmtValue PDH_FMT_COUNTERVALUE_LONG } +// PDH_RAW_COUNTER structure contains the raw data value of a counter. +type PDH_RAW_COUNTER struct { + CStatus uint32 // Counter status that indicates if the counter value is valid. + TimeStamp FILETIME // Time at which the sample was taken. + FirstValue int64 // First raw counter value. + SecondValue int64 // Second raw counter value (used for some calculations). + MultiCount uint32 // Counter type-specific value. +} + +// PDH_RAW_COUNTER_ITEM structure contains the raw counter value for a specific instance. +type PDH_RAW_COUNTER_ITEM struct { + SzName *uint16 // Pointer to the instance name. + RawValue PDH_RAW_COUNTER // Raw counter value for the instance. +} + // PDH_COUNTER_INFO structure contains information describing the properties of a counter. This information also includes the counter path. type PDH_COUNTER_INFO struct { // Size of the structure, including the appended strings, in bytes. diff --git a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/performance_query.go b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/performance_query.go index 5c075e14e001c..f89f7705ef407 100644 --- a/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/performance_query.go +++ b/pkg/winperfcounters/internal/third_party/telegraf/win_perf_counters/performance_query.go @@ -11,12 +11,18 @@ import ( "unsafe" ) -// PerformanceQuery is abstraction for PDH_FMT_COUNTERVALUE_ITEM_DOUBLE +// CounterValue is abstraction for PDH_FMT_COUNTERVALUE_ITEM_DOUBLE type CounterValue struct { InstanceName string Value float64 } +// RawCounterValue is abstraction for PDH_RAW_COUNTER_ITEM +type RawCounterValue struct { + InstanceName string + RawValue int64 +} + // PerformanceQuery provides wrappers around Windows performance counters API for easy usage in GO type PerformanceQuery interface { Open() error @@ -26,6 +32,8 @@ type PerformanceQuery interface { GetCounterPath(counterHandle PDH_HCOUNTER) (string, error) GetFormattedCounterValueDouble(hCounter PDH_HCOUNTER) (float64, error) GetFormattedCounterArrayDouble(hCounter PDH_HCOUNTER) ([]CounterValue, error) + GetRawCounterValue(hCounter PDH_HCOUNTER) (int64, error) + GetRawCounterArray(hCounter PDH_HCOUNTER) ([]RawCounterValue, error) CollectData() error CollectDataWithTime() (time.Time, error) IsVistaOrNewer() bool @@ -163,6 +171,45 @@ func (m *PerformanceQueryImpl) GetFormattedCounterArrayDouble(hCounter PDH_HCOUN return nil, NewPdhError(ret) } +func (m *PerformanceQueryImpl) GetRawCounterValue(hCounter PDH_HCOUNTER) (int64, error) { + var counterType uint32 + var rawValue PDH_RAW_COUNTER + var ret uint32 + + if ret = PdhGetRawCounterValue(hCounter, &counterType, &rawValue); ret == ERROR_SUCCESS { + if rawValue.CStatus == PDH_CSTATUS_VALID_DATA { + return rawValue.FirstValue, nil + } else { + return 0, NewPdhError(rawValue.CStatus) + } + } else { + return 0, NewPdhError(ret) + } +} + +func (m *PerformanceQueryImpl) GetRawCounterArray(hCounter PDH_HCOUNTER) ([]RawCounterValue, error) { + var buffSize uint32 + var itemCount uint32 + var ret uint32 + + if ret = PdhGetRawCounterArrayW(hCounter, &buffSize, &itemCount, nil); ret == PDH_MORE_DATA { + buff := make([]byte, buffSize) + + if ret = PdhGetRawCounterArrayW(hCounter, &buffSize, &itemCount, &buff[0]); ret == ERROR_SUCCESS { + items := unsafe.Slice((*PDH_RAW_COUNTER_ITEM)(unsafe.Pointer(&buff[0])), itemCount) + values := make([]RawCounterValue, 0, itemCount) + for _, item := range items { + if item.RawValue.CStatus == PDH_CSTATUS_VALID_DATA { + val := RawCounterValue{UTF16PtrToString(item.SzName), item.RawValue.FirstValue} + values = append(values, val) + } + } + return values, nil + } + } + return nil, NewPdhError(ret) +} + func (m *PerformanceQueryImpl) CollectData() error { var ret uint32 if m.query == 0 { diff --git a/pkg/winperfcounters/watcher.go b/pkg/winperfcounters/watcher.go index a38e5369c9948..2d80cfed9052a 100644 --- a/pkg/winperfcounters/watcher.go +++ b/pkg/winperfcounters/watcher.go @@ -23,13 +23,20 @@ type PerfCounterWatcher interface { Path() string // ScrapeData collects a measurement and returns the value(s). ScrapeData() ([]CounterValue, error) + // ScrapeRawValue collects a measurement and returns the raw value. + ScrapeRawValue(rawValue *int64) (bool, error) + // ScrapeRawValues collects a measurement and returns the raw value(s) for all instances. + ScrapeRawValues() ([]RawCounterValue, error) // Resets the perfcounter query. Reset() error // Close all counters/handles related to the query and free all associated memory. Close() error } -type CounterValue = win_perf_counters.CounterValue +type ( + CounterValue = win_perf_counters.CounterValue + RawCounterValue = win_perf_counters.RawCounterValue +) type perfCounter struct { path string @@ -127,26 +134,12 @@ func (pc *perfCounter) Path() string { } func (pc *perfCounter) ScrapeData() ([]CounterValue, error) { - if err := pc.query.CollectData(); err != nil { - var pdhErr *win_perf_counters.PdhError - if !errors.As(err, &pdhErr) || (pdhErr.ErrorCode != win_perf_counters.PDH_NO_DATA && pdhErr.ErrorCode != win_perf_counters.PDH_CALC_NEGATIVE_DENOMINATOR) { - return nil, fmt.Errorf("failed to collect data for performance counter '%s': %w", pc.path, err) - } - - if pdhErr.ErrorCode == win_perf_counters.PDH_NO_DATA { - // No data is available for the counter, so return an empty slice. - return nil, nil - } - - if pdhErr.ErrorCode == win_perf_counters.PDH_CALC_NEGATIVE_DENOMINATOR { - // A counter rolled over, so the value is invalid - // See https://support.microfocus.com/kb/doc.php?id=7010545 - // Wait one second and retry once - time.Sleep(time.Second) - if retryErr := pc.query.CollectData(); retryErr != nil { - return nil, fmt.Errorf("failed retry for performance counter '%s': %w", pc.path, err) - } - } + hasData, err := pc.collectDataForScrape() + if err != nil { + return nil, err + } + if !hasData { + return nil, nil } vals, err := pc.query.GetFormattedCounterArrayDouble(pc.handle) @@ -158,21 +151,79 @@ func (pc *perfCounter) ScrapeData() ([]CounterValue, error) { return vals, nil } +func (pc *perfCounter) ScrapeRawValues() ([]RawCounterValue, error) { + hasData, err := pc.collectDataForScrape() + if err != nil { + return nil, err + } + if !hasData { + return nil, nil + } + + vals, err := pc.query.GetRawCounterArray(pc.handle) + if err != nil { + return nil, fmt.Errorf("failed to get raw data for performance counter '%s': %w", pc.path, err) + } + + vals = cleanupScrapedValues(vals) + return vals, nil +} + +func (pc *perfCounter) ScrapeRawValue(rawValue *int64) (bool, error) { + *rawValue = 0 + hasData, err := pc.collectDataForScrape() + if err != nil { + return false, err + } + if !hasData { + return false, nil + } + + *rawValue, err = pc.query.GetRawCounterValue(pc.handle) + if err != nil { + return false, fmt.Errorf("failed to get raw data for performance counter '%s': %w", pc.path, err) + } + + return true, nil +} + // ExpandWildCardPath examines the local computer and returns those counter paths that match the given counter path which contains wildcard characters. func ExpandWildCardPath(counterPath string) ([]string, error) { return win_perf_counters.ExpandWildCardPath(counterPath) } +func getInstanceName(ctr any) string { + switch v := ctr.(type) { + case win_perf_counters.CounterValue: + return v.InstanceName + case win_perf_counters.RawCounterValue: + return v.InstanceName + default: + panic(fmt.Sprintf("unexpected type %T", v)) + } +} + +func setInstanceName(ctr any, name string) { + switch v := ctr.(type) { + case *win_perf_counters.CounterValue: + v.InstanceName = name + case *win_perf_counters.RawCounterValue: + v.InstanceName = name + default: + panic(fmt.Sprintf("unexpected type %T", v)) + } +} + // cleanupScrapedValues handles instance name collisions and standardizes names. // It cleans up the list in-place to avoid unnecessary copies. -func cleanupScrapedValues(vals []CounterValue) []CounterValue { +func cleanupScrapedValues[C CounterValue | RawCounterValue](vals []C) []C { if len(vals) == 0 { return vals } // If there is only one "_Total" instance, clear the instance name. - if len(vals) == 1 && vals[0].InstanceName == totalInstanceName { - vals[0].InstanceName = "" + if len(vals) == 1 && getInstanceName(vals[0]) == totalInstanceName { + setInstanceName(&vals[0], "") return vals } @@ -180,7 +231,7 @@ func cleanupScrapedValues(vals []CounterValue) []CounterValue { totalIndex := -1 for i := range vals { - instanceName := vals[i].InstanceName + instanceName := getInstanceName(vals[i]) if instanceName == totalInstanceName { // Remember if a "_Total" instance was present. @@ -190,7 +241,7 @@ func cleanupScrapedValues(vals []CounterValue) []CounterValue { if n, ok := occurrences[instanceName]; ok { // Append indices to duplicate instance names. occurrences[instanceName]++ - vals[i].InstanceName = fmt.Sprintf("%s#%d", instanceName, n) + setInstanceName(&vals[i], fmt.Sprintf("%s#%d", instanceName, n)) } else { occurrences[instanceName] = 1 } @@ -204,8 +255,35 @@ func cleanupScrapedValues(vals []CounterValue) []CounterValue { return vals } -func removeItemAt(vals []CounterValue, idx int) []CounterValue { +func removeItemAt[C CounterValue | RawCounterValue](vals []C, idx int) []C { vals[idx] = vals[len(vals)-1] - vals[len(vals)-1] = CounterValue{} + var zeroValue C + vals[len(vals)-1] = zeroValue return vals[:len(vals)-1] } + +func (pc *perfCounter) collectDataForScrape() (bool, error) { + if err := pc.query.CollectData(); err != nil { + var pdhErr *win_perf_counters.PdhError + if !errors.As(err, &pdhErr) || (pdhErr.ErrorCode != win_perf_counters.PDH_NO_DATA && pdhErr.ErrorCode != win_perf_counters.PDH_CALC_NEGATIVE_DENOMINATOR) { + return false, fmt.Errorf("failed to collect data for performance counter '%s': %w", pc.path, err) + } + + if pdhErr.ErrorCode == win_perf_counters.PDH_NO_DATA { + // No data is available for the counter, so no error but also no data + return false, nil + } + + if pdhErr.ErrorCode == win_perf_counters.PDH_CALC_NEGATIVE_DENOMINATOR { + // A counter rolled over, so the value is invalid + // See https://support.microfocus.com/kb/doc.php?id=7010545 + // Wait one second and retry once + time.Sleep(time.Second) + if retryErr := pc.query.CollectData(); retryErr != nil { + return false, fmt.Errorf("failed retry for performance counter '%s': %w", pc.path, err) + } + } + } + + return true, nil +} diff --git a/pkg/winperfcounters/watcher_test.go b/pkg/winperfcounters/watcher_test.go index df3e282217356..09ab4d81adb60 100644 --- a/pkg/winperfcounters/watcher_test.go +++ b/pkg/winperfcounters/watcher_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/sys/windows" ) func TestCounterPath(t *testing.T) { @@ -51,7 +52,47 @@ func Test_Scraping_Wildcard(t *testing.T) { values, err := watcher.ScrapeData() require.NoError(t, err) - require.GreaterOrEqual(t, len(values), 3) + // Count the number of logical drives + drives, err := windows.GetLogicalDrives() + require.NoError(t, err) + + numDrives := 0 + for drives != 0 { + if drives&1 != 0 { + numDrives++ + } + drives >>= 1 + } + + require.GreaterOrEqual(t, len(values), numDrives) +} + +func TestWatcher_ScrapeRawValue(t *testing.T) { + watcher, err := NewWatcher("Memory", "", "Page Reads/Sec") + require.NoError(t, err) + defer func() { + require.NoError(t, watcher.Close()) + }() + + var rawValue int64 + hasValue, err := watcher.ScrapeRawValue(&rawValue) + require.NoError(t, err) + require.True(t, hasValue) + assert.Positive(t, rawValue) +} + +func TestWatcher_ScrapeRawValue_NoData(t *testing.T) { + watcher, err := NewWatcher(".NET CLR Memory", "NonExistingInstance", "% Time in GC") + require.NoError(t, err) + defer func() { + require.NoError(t, watcher.Close()) + }() + + var rawValue int64 + hasValue, err := watcher.ScrapeRawValue(&rawValue) + require.NoError(t, err) + assert.False(t, hasValue) + assert.Zero(t, rawValue) } func TestNewPerfCounter_InvalidPath(t *testing.T) { @@ -138,11 +179,12 @@ func TestPerfCounter_Reset(t *testing.T) { } } -func TestPerfCounter_ScrapeData(t *testing.T) { +func TestPerfCounter_Scrape(t *testing.T) { type testCase struct { - name string - path string - assertExpected func(t *testing.T, data []CounterValue) + name string + path string + assertExpected func(t *testing.T, data []CounterValue) + assertExpectedRaw func(t *testing.T, data []RawCounterValue) } testCases := []testCase{ @@ -153,6 +195,10 @@ func TestPerfCounter_ScrapeData(t *testing.T) { assert.Len(t, data, 1) assert.Empty(t, data[0].InstanceName) }, + assertExpectedRaw: func(t *testing.T, raw []RawCounterValue) { + assert.Len(t, raw, 1) + assert.Empty(t, raw[0].InstanceName) + }, }, { name: "total instance", @@ -161,6 +207,10 @@ func TestPerfCounter_ScrapeData(t *testing.T) { assert.Len(t, data, 1) assert.Empty(t, data[0].InstanceName) }, + assertExpectedRaw: func(t *testing.T, raw []RawCounterValue) { + assert.Len(t, raw, 1) + assert.Empty(t, raw[0].InstanceName) + }, }, { name: "all instances", @@ -171,6 +221,12 @@ func TestPerfCounter_ScrapeData(t *testing.T) { assert.NotEmpty(t, d.InstanceName) } }, + assertExpectedRaw: func(t *testing.T, raw []RawCounterValue) { + assert.GreaterOrEqual(t, len(raw), 1) + for _, r := range raw { + assert.NotEmpty(t, r.InstanceName) + } + }, }, } @@ -181,8 +237,11 @@ func TestPerfCounter_ScrapeData(t *testing.T) { data, err := pc.ScrapeData() require.NoError(t, err, "Failed to scrape data: %v", err) - test.assertExpected(t, data) + + raw, err := pc.ScrapeRawValues() + require.NoError(t, err, "Failed to scrape raw data: %v", err) + test.assertExpectedRaw(t, raw) }) } } diff --git a/receiver/activedirectorydsreceiver/scraper_test.go b/receiver/activedirectorydsreceiver/scraper_test.go index 0528040182a92..4347c50ef5cd4 100644 --- a/receiver/activedirectorydsreceiver/scraper_test.go +++ b/receiver/activedirectorydsreceiver/scraper_test.go @@ -140,6 +140,16 @@ type mockPerfCounterWatcher struct { closed bool } +// ScrapeRawValue implements winperfcounters.PerfCounterWatcher. +func (w *mockPerfCounterWatcher) ScrapeRawValue(_ *int64) (bool, error) { + panic("unimplemented") +} + +// ScrapeRawValues implements winperfcounters.PerfCounterWatcher. +func (w *mockPerfCounterWatcher) ScrapeRawValues() ([]winperfcounters.RawCounterValue, error) { + panic("unimplemented") +} + // Reset panics; it should not be called func (mockPerfCounterWatcher) Reset() error { panic("mockPerfCounterWatcher::Reset is not implemented") diff --git a/receiver/iisreceiver/scraper_test.go b/receiver/iisreceiver/scraper_test.go index 6b9f6c2ec0c08..1841ecb810d9c 100644 --- a/receiver/iisreceiver/scraper_test.go +++ b/receiver/iisreceiver/scraper_test.go @@ -175,6 +175,16 @@ func newMockWatcherFactorFromPath(watchErr error, value float64) func(string) (w } } +// ScrapeRawValue implements winperfcounters.PerfCounterWatcher. +func (mpc *mockPerfCounter) ScrapeRawValue(_ *int64) (bool, error) { + panic("unimplemented") +} + +// ScrapeRawValues implements winperfcounters.PerfCounterWatcher. +func (mpc *mockPerfCounter) ScrapeRawValues() ([]winperfcounters.RawCounterValue, error) { + panic("unimplemented") +} + // Path func (mpc *mockPerfCounter) Path() string { return "" diff --git a/receiver/sqlserverreceiver/scraper_windows_test.go b/receiver/sqlserverreceiver/scraper_windows_test.go index 8e960ead105d0..6c8443b54deae 100644 --- a/receiver/sqlserverreceiver/scraper_windows_test.go +++ b/receiver/sqlserverreceiver/scraper_windows_test.go @@ -28,6 +28,16 @@ type mockPerfCounterWatcher struct { mock.Mock } +// ScrapeRawValue implements winperfcounters.PerfCounterWatcher. +func (_m *mockPerfCounterWatcher) ScrapeRawValue(_ *int64) (bool, error) { + panic("unimplemented") +} + +// ScrapeRawValues implements winperfcounters.PerfCounterWatcher. +func (_m *mockPerfCounterWatcher) ScrapeRawValues() ([]winperfcounters.RawCounterValue, error) { + panic("unimplemented") +} + // Close provides a mock function with given fields: func (_m *mockPerfCounterWatcher) Close() error { ret := _m.Called() diff --git a/receiver/windowsperfcountersreceiver/windowsperfcounters_scraper_test.go b/receiver/windowsperfcountersreceiver/windowsperfcounters_scraper_test.go index 1759da85450a6..eda76c9c3b71c 100644 --- a/receiver/windowsperfcountersreceiver/windowsperfcounters_scraper_test.go +++ b/receiver/windowsperfcountersreceiver/windowsperfcounters_scraper_test.go @@ -37,6 +37,16 @@ type mockPerfCounter struct { resetErr error } +// ScrapeRawValue implements winperfcounters.PerfCounterWatcher. +func (w *mockPerfCounter) ScrapeRawValue(_ *int64) (bool, error) { + panic("unimplemented") +} + +// ScrapeRawValues implements winperfcounters.PerfCounterWatcher. +func (w *mockPerfCounter) ScrapeRawValues() ([]winperfcounters.RawCounterValue, error) { + panic("unimplemented") +} + func (w *mockPerfCounter) Reset() error { return w.resetErr }