mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-09 06:26:39 +00:00
process: fix fallback to V1 collector (#1667)
This commit is contained in:
@@ -162,6 +162,7 @@ func (c *Collector) Build(logger *slog.Logger, wmiClient *wmi.Client) error {
|
||||
|
||||
if utils.PDHEnabled() {
|
||||
counters := []string{
|
||||
processID,
|
||||
percentProcessorTime,
|
||||
percentPrivilegedTime,
|
||||
percentUserTime,
|
||||
@@ -181,7 +182,6 @@ func (c *Collector) Build(logger *slog.Logger, wmiClient *wmi.Client) error {
|
||||
pageFileBytes,
|
||||
poolNonPagedBytes,
|
||||
poolPagedBytes,
|
||||
processID,
|
||||
priorityBase,
|
||||
privateBytes,
|
||||
threadCount,
|
||||
@@ -195,37 +195,8 @@ func (c *Collector) Build(logger *slog.Logger, wmiClient *wmi.Client) error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector("Process V2", c.config.PerfCounterInstances, counters)
|
||||
if errors.Is(err, perfdata.NewPdhError(perfdata.PdhNoData)) {
|
||||
counters = []string{
|
||||
percentProcessorTime,
|
||||
percentPrivilegedTime,
|
||||
percentUserTime,
|
||||
creatingProcessID,
|
||||
elapsedTime,
|
||||
handleCount,
|
||||
idProcess,
|
||||
ioDataBytesPerSec,
|
||||
ioDataOperationsPerSec,
|
||||
ioOtherBytesPerSec,
|
||||
ioOtherOperationsPerSec,
|
||||
ioReadBytesPerSec,
|
||||
ioReadOperationsPerSec,
|
||||
ioWriteBytesPerSec,
|
||||
ioWriteOperationsPerSec,
|
||||
pageFaultsPerSec,
|
||||
pageFileBytesPeak,
|
||||
pageFileBytes,
|
||||
poolNonPagedBytes,
|
||||
poolPagedBytes,
|
||||
priorityBase,
|
||||
privateBytes,
|
||||
threadCount,
|
||||
virtualBytesPeak,
|
||||
virtualBytes,
|
||||
workingSetPrivate,
|
||||
workingSetPeak,
|
||||
workingSet,
|
||||
}
|
||||
if errors.Is(err, perfdata.NewPdhError(perfdata.PdhCstatusNoObject)) {
|
||||
counters[0] = idProcess
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector("Process", c.config.PerfCounterInstances, counters)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
package process_test
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/process"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
func BenchmarkProcessCollector(b *testing.B) {
|
||||
@@ -15,3 +22,49 @@ func BenchmarkProcessCollector(b *testing.B) {
|
||||
// No context name required as collector source is WMI
|
||||
testutils.FuncBenchmarkCollector(b, process.Name, process.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestProcessCollector(t *testing.T) {
|
||||
t.Setenv("WINDOWS_EXPORTER_PERF_COUNTERS_ENGINE", "pdh")
|
||||
|
||||
var (
|
||||
metrics []prometheus.Metric
|
||||
err error
|
||||
)
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||
c := process.New(nil)
|
||||
ch := make(chan prometheus.Metric, 10000)
|
||||
|
||||
wmiClient := &wmi.Client{
|
||||
AllowMissingFields: true,
|
||||
}
|
||||
wmiClient.SWbemServicesClient, err = wmi.InitializeSWbemServices(wmiClient)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c.Close(logger))
|
||||
})
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
for metric := range ch {
|
||||
metrics = append(metrics, metric)
|
||||
}
|
||||
}()
|
||||
|
||||
require.NoError(t, c.Build(logger, wmiClient))
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
require.NoError(t, c.Collect(nil, logger, ch))
|
||||
|
||||
close(ch)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
require.NotEmpty(t, metrics)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
package perfdata
|
||||
|
||||
import "errors"
|
||||
|
||||
// Error represents error returned from Performance Counters API.
|
||||
type Error struct {
|
||||
ErrorCode uint32
|
||||
errorText string
|
||||
}
|
||||
|
||||
func (m *Error) Is(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var e *Error
|
||||
if errors.As(err, &e) {
|
||||
return m.ErrorCode == e.ErrorCode
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Error) Error() string {
|
||||
return m.errorText
|
||||
}
|
||||
|
||||
@@ -57,92 +57,92 @@ type (
|
||||
// PDH error codes, which can be returned by all Pdh* functions. Taken from mingw-w64 pdhmsg.h
|
||||
|
||||
const (
|
||||
PdhCstatusValidData = 0x00000000 // The returned data is valid.
|
||||
PdhCstatusNewData = 0x00000001 // The return data value is valid and different from the last sample.
|
||||
PdhCstatusNoMachine = 0x800007D0 // Unable to connect to the specified computer, or the computer is offline.
|
||||
PdhCstatusNoInstance = 0x800007D1
|
||||
PdhMoreData = 0x800007D2 // The PdhGetFormattedCounterArray* function can return this if there's 'more data to be displayed'.
|
||||
PdhCstatusItemNotValidated = 0x800007D3
|
||||
PdhRetry = 0x800007D4
|
||||
PdhNoData = 0x800007D5 // The query does not currently contain any counters (for example, limited access)
|
||||
PdhCalcNegativeDenominator = 0x800007D6
|
||||
PdhCalcNegativeTimebase = 0x800007D7
|
||||
PdhCalcNegativeValue = 0x800007D8
|
||||
PdhDialogCancelled = 0x800007D9
|
||||
PdhEndOfLogFile = 0x800007DA
|
||||
PdhAsyncQueryTimeout = 0x800007DB
|
||||
PdhCannotSetDefaultRealtimeDatasource = 0x800007DC
|
||||
PdhCstatusNoObject = 0xC0000BB8
|
||||
PdhCstatusNoCounter = 0xC0000BB9 // The specified counter could not be found.
|
||||
PdhCstatusInvalidData = 0xC0000BBA // The counter was successfully found, but the data returned is not valid.
|
||||
PdhMemoryAllocationFailure = 0xC0000BBB
|
||||
PdhInvalidHandle = 0xC0000BBC
|
||||
PdhInvalidArgument = 0xC0000BBD // Required argument is missing or incorrect.
|
||||
PdhFunctionNotFound = 0xC0000BBE
|
||||
PdhCstatusNoCountername = 0xC0000BBF
|
||||
PdhCstatusBadCountername = 0xC0000BC0 // Unable to parse the counter path. Check the format and syntax of the specified path.
|
||||
PdhInvalidBuffer = 0xC0000BC1
|
||||
PdhInsufficientBuffer = 0xC0000BC2
|
||||
PdhCannotConnectMachine = 0xC0000BC3
|
||||
PdhInvalidPath = 0xC0000BC4
|
||||
PdhInvalidInstance = 0xC0000BC5
|
||||
PdhInvalidData = 0xC0000BC6 // specified counter does not contain valid data or a successful status code.
|
||||
PdhNoDialogData = 0xC0000BC7
|
||||
PdhCannotReadNameStrings = 0xC0000BC8
|
||||
PdhLogFileCreateError = 0xC0000BC9
|
||||
PdhLogFileOpenError = 0xC0000BCA
|
||||
PdhLogTypeNotFound = 0xC0000BCB
|
||||
PdhNoMoreData = 0xC0000BCC
|
||||
PdhEntryNotInLogFile = 0xC0000BCD
|
||||
PdhDataSourceIsLogFile = 0xC0000BCE
|
||||
PdhDataSourceIsRealTime = 0xC0000BCF
|
||||
PdhUnableReadLogHeader = 0xC0000BD0
|
||||
PdhFileNotFound = 0xC0000BD1
|
||||
PdhFileAlreadyExists = 0xC0000BD2
|
||||
PdhNotImplemented = 0xC0000BD3
|
||||
PdhStringNotFound = 0xC0000BD4
|
||||
PdhUnableMapNameFiles = 0x80000BD5
|
||||
PdhUnknownLogFormat = 0xC0000BD6
|
||||
PdhUnknownLogsvcCommand = 0xC0000BD7
|
||||
PdhLogsvcQueryNotFound = 0xC0000BD8
|
||||
PdhLogsvcNotOpened = 0xC0000BD9
|
||||
PdhWbemError = 0xC0000BDA
|
||||
PdhAccessDenied = 0xC0000BDB
|
||||
PdhLogFileTooSmall = 0xC0000BDC
|
||||
PdhInvalidDatasource = 0xC0000BDD
|
||||
PdhInvalidSqldb = 0xC0000BDE
|
||||
PdhNoCounters = 0xC0000BDF
|
||||
PdhSQLAllocFailed = 0xC0000BE0
|
||||
PdhSQLAllocconFailed = 0xC0000BE1
|
||||
PdhSQLExecDirectFailed = 0xC0000BE2
|
||||
PdhSQLFetchFailed = 0xC0000BE3
|
||||
PdhSQLRowcountFailed = 0xC0000BE4
|
||||
PdhSQLMoreResultsFailed = 0xC0000BE5
|
||||
PdhSQLConnectFailed = 0xC0000BE6
|
||||
PdhSQLBindFailed = 0xC0000BE7
|
||||
PdhCannotConnectWmiServer = 0xC0000BE8
|
||||
PdhPlaCollectionAlreadyRunning = 0xC0000BE9
|
||||
PdhPlaErrorScheduleOverlap = 0xC0000BEA
|
||||
PdhPlaCollectionNotFound = 0xC0000BEB
|
||||
PdhPlaErrorScheduleElapsed = 0xC0000BEC
|
||||
PdhPlaErrorNostart = 0xC0000BED
|
||||
PdhPlaErrorAlreadyExists = 0xC0000BEE
|
||||
PdhPlaErrorTypeMismatch = 0xC0000BEF
|
||||
PdhPlaErrorFilepath = 0xC0000BF0
|
||||
PdhPlaServiceError = 0xC0000BF1
|
||||
PdhPlaValidationError = 0xC0000BF2
|
||||
PdhPlaValidationWarning = 0x80000BF3
|
||||
PdhPlaErrorNameTooLong = 0xC0000BF4
|
||||
PdhInvalidSQLLogFormat = 0xC0000BF5
|
||||
PdhCounterAlreadyInQuery = 0xC0000BF6
|
||||
PdhBinaryLogCorrupt = 0xC0000BF7
|
||||
PdhLogSampleTooSmall = 0xC0000BF8
|
||||
PdhOsLaterVersion = 0xC0000BF9
|
||||
PdhOsEarlierVersion = 0xC0000BFA
|
||||
PdhIncorrectAppendTime = 0xC0000BFB
|
||||
PdhUnmatchedAppendCounter = 0xC0000BFC
|
||||
PdhSQLAlterDetailFailed = 0xC0000BFD
|
||||
PdhQueryPerfDataTimeout = 0xC0000BFE
|
||||
PdhCstatusValidData uint32 = 0x00000000 // The returned data is valid.
|
||||
PdhCstatusNewData uint32 = 0x00000001 // The return data value is valid and different from the last sample.
|
||||
PdhCstatusNoMachine uint32 = 0x800007D0 // Unable to connect to the specified computer, or the computer is offline.
|
||||
PdhCstatusNoInstance uint32 = 0x800007D1
|
||||
PdhMoreData uint32 = 0x800007D2 // The PdhGetFormattedCounterArray* function can return this if there's 'more data to be displayed'.
|
||||
PdhCstatusItemNotValidated uint32 = 0x800007D3
|
||||
PdhRetry uint32 = 0x800007D4
|
||||
PdhNoData uint32 = 0x800007D5 // The query does not currently contain any counters (for example, limited access)
|
||||
PdhCalcNegativeDenominator uint32 = 0x800007D6
|
||||
PdhCalcNegativeTimebase uint32 = 0x800007D7
|
||||
PdhCalcNegativeValue uint32 = 0x800007D8
|
||||
PdhDialogCancelled uint32 = 0x800007D9
|
||||
PdhEndOfLogFile uint32 = 0x800007DA
|
||||
PdhAsyncQueryTimeout uint32 = 0x800007DB
|
||||
PdhCannotSetDefaultRealtimeDatasource uint32 = 0x800007DC
|
||||
PdhCstatusNoObject uint32 = 0xC0000BB8
|
||||
PdhCstatusNoCounter uint32 = 0xC0000BB9 // The specified counter could not be found.
|
||||
PdhCstatusInvalidData uint32 = 0xC0000BBA // The counter was successfully found, but the data returned is not valid.
|
||||
PdhMemoryAllocationFailure uint32 = 0xC0000BBB
|
||||
PdhInvalidHandle uint32 = 0xC0000BBC
|
||||
PdhInvalidArgument uint32 = 0xC0000BBD // Required argument is missing or incorrect.
|
||||
PdhFunctionNotFound uint32 = 0xC0000BBE
|
||||
PdhCstatusNoCountername uint32 = 0xC0000BBF
|
||||
PdhCstatusBadCountername uint32 = 0xC0000BC0 // Unable to parse the counter path. Check the format and syntax of the specified path.
|
||||
PdhInvalidBuffer uint32 = 0xC0000BC1
|
||||
PdhInsufficientBuffer uint32 = 0xC0000BC2
|
||||
PdhCannotConnectMachine uint32 = 0xC0000BC3
|
||||
PdhInvalidPath uint32 = 0xC0000BC4
|
||||
PdhInvalidInstance uint32 = 0xC0000BC5
|
||||
PdhInvalidData uint32 = 0xC0000BC6 // specified counter does not contain valid data or a successful status code.
|
||||
PdhNoDialogData uint32 = 0xC0000BC7
|
||||
PdhCannotReadNameStrings uint32 = 0xC0000BC8
|
||||
PdhLogFileCreateError uint32 = 0xC0000BC9
|
||||
PdhLogFileOpenError uint32 = 0xC0000BCA
|
||||
PdhLogTypeNotFound uint32 = 0xC0000BCB
|
||||
PdhNoMoreData uint32 = 0xC0000BCC
|
||||
PdhEntryNotInLogFile uint32 = 0xC0000BCD
|
||||
PdhDataSourceIsLogFile uint32 = 0xC0000BCE
|
||||
PdhDataSourceIsRealTime uint32 = 0xC0000BCF
|
||||
PdhUnableReadLogHeader uint32 = 0xC0000BD0
|
||||
PdhFileNotFound uint32 = 0xC0000BD1
|
||||
PdhFileAlreadyExists uint32 = 0xC0000BD2
|
||||
PdhNotImplemented uint32 = 0xC0000BD3
|
||||
PdhStringNotFound uint32 = 0xC0000BD4
|
||||
PdhUnableMapNameFiles uint32 = 0x80000BD5
|
||||
PdhUnknownLogFormat uint32 = 0xC0000BD6
|
||||
PdhUnknownLogsvcCommand uint32 = 0xC0000BD7
|
||||
PdhLogsvcQueryNotFound uint32 = 0xC0000BD8
|
||||
PdhLogsvcNotOpened uint32 = 0xC0000BD9
|
||||
PdhWbemError uint32 = 0xC0000BDA
|
||||
PdhAccessDenied uint32 = 0xC0000BDB
|
||||
PdhLogFileTooSmall uint32 = 0xC0000BDC
|
||||
PdhInvalidDatasource uint32 = 0xC0000BDD
|
||||
PdhInvalidSqldb uint32 = 0xC0000BDE
|
||||
PdhNoCounters uint32 = 0xC0000BDF
|
||||
PdhSQLAllocFailed uint32 = 0xC0000BE0
|
||||
PdhSQLAllocconFailed uint32 = 0xC0000BE1
|
||||
PdhSQLExecDirectFailed uint32 = 0xC0000BE2
|
||||
PdhSQLFetchFailed uint32 = 0xC0000BE3
|
||||
PdhSQLRowcountFailed uint32 = 0xC0000BE4
|
||||
PdhSQLMoreResultsFailed uint32 = 0xC0000BE5
|
||||
PdhSQLConnectFailed uint32 = 0xC0000BE6
|
||||
PdhSQLBindFailed uint32 = 0xC0000BE7
|
||||
PdhCannotConnectWmiServer uint32 = 0xC0000BE8
|
||||
PdhPlaCollectionAlreadyRunning uint32 = 0xC0000BE9
|
||||
PdhPlaErrorScheduleOverlap uint32 = 0xC0000BEA
|
||||
PdhPlaCollectionNotFound uint32 = 0xC0000BEB
|
||||
PdhPlaErrorScheduleElapsed uint32 = 0xC0000BEC
|
||||
PdhPlaErrorNostart uint32 = 0xC0000BED
|
||||
PdhPlaErrorAlreadyExists uint32 = 0xC0000BEE
|
||||
PdhPlaErrorTypeMismatch uint32 = 0xC0000BEF
|
||||
PdhPlaErrorFilepath uint32 = 0xC0000BF0
|
||||
PdhPlaServiceError uint32 = 0xC0000BF1
|
||||
PdhPlaValidationError uint32 = 0xC0000BF2
|
||||
PdhPlaValidationWarning uint32 = 0x80000BF3
|
||||
PdhPlaErrorNameTooLong uint32 = 0xC0000BF4
|
||||
PdhInvalidSQLLogFormat uint32 = 0xC0000BF5
|
||||
PdhCounterAlreadyInQuery uint32 = 0xC0000BF6
|
||||
PdhBinaryLogCorrupt uint32 = 0xC0000BF7
|
||||
PdhLogSampleTooSmall uint32 = 0xC0000BF8
|
||||
PdhOsLaterVersion uint32 = 0xC0000BF9
|
||||
PdhOsEarlierVersion uint32 = 0xC0000BFA
|
||||
PdhIncorrectAppendTime uint32 = 0xC0000BFB
|
||||
PdhUnmatchedAppendCounter uint32 = 0xC0000BFC
|
||||
PdhSQLAlterDetailFailed uint32 = 0xC0000BFD
|
||||
PdhQueryPerfDataTimeout uint32 = 0xC0000BFE
|
||||
)
|
||||
|
||||
var PDHErrors = map[uint32]string{
|
||||
|
||||
@@ -3,6 +3,6 @@ package types
|
||||
import "regexp"
|
||||
|
||||
var (
|
||||
RegExpAny = regexp.MustCompile(".+")
|
||||
RegExpEmpty = regexp.MustCompile("")
|
||||
RegExpAny = regexp.MustCompile("^(?:.+)$")
|
||||
RegExpEmpty = regexp.MustCompile("^(?:)$")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user