*: Implement collector interface for registry perfdata (#1670)

This commit is contained in:
Jan-Otto Kröpke
2024-10-05 21:33:40 +02:00
committed by GitHub
parent 2a9a11bd01
commit 5952c51a39
53 changed files with 661 additions and 1267 deletions

View File

@@ -44,7 +44,7 @@ jobs:
run: | run: |
curl.exe -L https://github.com/moby/buildkit/releases/download/v${{ env.VERSION_BUILDKIT }}/buildkit-v${{ env.VERSION_BUILDKIT }}.windows-amd64.tar.gz -o buildkit.tar.gz curl.exe -L https://github.com/moby/buildkit/releases/download/v${{ env.VERSION_BUILDKIT }}/buildkit-v${{ env.VERSION_BUILDKIT }}.windows-amd64.tar.gz -o buildkit.tar.gz
tar.exe xvf buildkit.tar.gz tar.exe xvf buildkit.tar.gz
.\bin\buildkitd.exe --register-service .\bin\buildkitd.exe --register-service
Start-Service buildkitd Start-Service buildkitd
- name: Setup Docker Buildx - name: Setup Docker Buildx
@@ -75,32 +75,32 @@ jobs:
- name: Build - name: Build
run: | run: |
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
$Version = git describe --tags --always $Version = git describe --tags --always
$Version = $Version -replace 'v', '' $Version = $Version -replace 'v', ''
# '+' symbols are invalid characters in image tags # '+' symbols are invalid characters in image tags
$Version = $Version -replace '\+', '_' $Version = $Version -replace '\+', '_'
$Version | Set-Content VERSION -PassThru $Version | Set-Content VERSION -PassThru
make build-all make build-all
# GH requires all files to have different names, so add version/arch to differentiate # GH requires all files to have different names, so add version/arch to differentiate
foreach($Arch in "amd64", "arm64") { foreach($Arch in "amd64", "arm64") {
Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe
} }
Get-ChildItem -Path output Get-ChildItem -Path output
- name: Build Release Artifacts - name: Build Release Artifacts
run: | run: |
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
$Version = Get-Content VERSION $Version = Get-Content VERSION
foreach($Arch in "amd64", "arm64") { foreach($Arch in "amd64", "arm64") {
Write-Host "Building windows_exporter $Version msi for $Arch" Write-Host "Building windows_exporter $Version msi for $Arch"
.\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch" .\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch"
} }
Move-Item installer\*.msi output\ Move-Item installer\*.msi output\
Get-ChildItem -Path output\ Get-ChildItem -Path output\
@@ -119,7 +119,7 @@ jobs:
env: env:
VERSION: >- VERSION: >-
${{ ${{
startsWith(github.ref, 'refs/tags/') && 'latest' || startsWith(github.ref, 'refs/tags/') && 'latest' ||
( (
github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || github.ref_name github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || github.ref_name
) )

View File

@@ -83,7 +83,7 @@ issues:
- text: "don't use ALL_CAPS in Go names; use CamelCase" - text: "don't use ALL_CAPS in Go names; use CamelCase"
linters: linters:
- revive - revive
- path: internal/perflib/ - path: internal/perfdata/v1/
linters: linters:
- godox - godox
- stylecheck - stylecheck

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -25,7 +25,7 @@ var ConfigDefaults = Config{}
type Collector struct { type Collector struct {
config Config config Config
perfDataCollector *perfdata.Collector perfDataCollector perfdata.Collector
challengeResponseProcessingTime *prometheus.Desc challengeResponseProcessingTime *prometheus.Desc
challengeResponsesPerSecond *prometheus.Desc challengeResponsesPerSecond *prometheus.Desc
@@ -94,7 +94,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
var err error var err error
c.perfDataCollector, err = perfdata.NewCollector("Certification Authority", []string{"*"}, counters) c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Certification Authority", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create Certification Authority collector: %w", err) return fmt.Errorf("failed to create Certification Authority collector: %w", err)
} }
@@ -206,7 +206,7 @@ func (c *Collector) collectADCSCounters(ctx *types.ScrapeContext, logger *slog.L
return errors.New("perflib did not contain an entry for Certification Authority") return errors.New("perflib did not contain an entry for Certification Authority")
} }
err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, logger) err := v1.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, logger)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -12,7 +12,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -28,7 +28,7 @@ var ConfigDefaults = Config{}
type Collector struct { type Collector struct {
config Config config Config
perfDataCollector *perfdata.Collector perfDataCollector perfdata.Collector
adLoginConnectionFailures *prometheus.Desc adLoginConnectionFailures *prometheus.Desc
artifactDBFailures *prometheus.Desc artifactDBFailures *prometheus.Desc
@@ -157,7 +157,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
var err error var err error
c.perfDataCollector, err = perfdata.NewCollector("AD FS", []string{"*"}, counters) c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "AD FS", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create AD FS collector: %w", err) return fmt.Errorf("failed to create AD FS collector: %w", err)
} }
@@ -438,7 +438,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
var adfsData []perflibADFS var adfsData []perflibADFS
err := perflib.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, logger) err := v1.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, logger)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -9,7 +9,8 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perflib" "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -26,7 +27,7 @@ var ConfigDefaults = Config{}
type Collector struct { type Collector struct {
config Config config Config
perfDataCollector *perfdata.Collector perfDataCollector perfdata.Collector
asyncCopyReadsTotal *prometheus.Desc asyncCopyReadsTotal *prometheus.Desc
asyncDataMapsTotal *prometheus.Desc asyncDataMapsTotal *prometheus.Desc
@@ -127,7 +128,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
var err error var err error
c.perfDataCollector, err = perfdata.NewCollector("Cache", []string{"*"}, counters) c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Cache", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create Cache collector: %w", err) return fmt.Errorf("failed to create Cache collector: %w", err)
} }
@@ -332,7 +333,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []perflibCache // Single-instance class, array is required but will have single entry. var dst []perflibCache // Single-instance class, array is required but will have single entry.
if err := perflib.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, logger); err != nil {
return err return err
} }
@@ -523,7 +524,7 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
return fmt.Errorf("failed to collect Cache metrics: %w", err) return fmt.Errorf("failed to collect Cache metrics: %w", err)
} }
cacheData, ok := data["*"] cacheData, ok := data[perftypes.EmptyInstance]
if !ok { if !ok {
return errors.New("perflib query for Cache returned empty result set") return errors.New("perflib query for Cache returned empty result set")

View File

@@ -10,7 +10,7 @@ import (
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -325,19 +325,19 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.runtimeTotal, c.runtimeTotal,
prometheus.CounterValue, prometheus.CounterValue,
float64(containerStats.Processor.TotalRuntime100ns)*perflib.TicksToSecondScaleFactor, float64(containerStats.Processor.TotalRuntime100ns)*perftypes.TicksToSecondScaleFactor,
containerIdWithPrefix, containerIdWithPrefix,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.runtimeUser, c.runtimeUser,
prometheus.CounterValue, prometheus.CounterValue,
float64(containerStats.Processor.RuntimeUser100ns)*perflib.TicksToSecondScaleFactor, float64(containerStats.Processor.RuntimeUser100ns)*perftypes.TicksToSecondScaleFactor,
containerIdWithPrefix, containerIdWithPrefix,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.runtimeKernel, c.runtimeKernel,
prometheus.CounterValue, prometheus.CounterValue,
float64(containerStats.Processor.RuntimeKernel100ns)*perflib.TicksToSecondScaleFactor, float64(containerStats.Processor.RuntimeKernel100ns)*perftypes.TicksToSecondScaleFactor,
containerIdWithPrefix, containerIdWithPrefix,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(

View File

@@ -9,7 +9,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -25,7 +25,7 @@ var ConfigDefaults = Config{}
type Collector struct { type Collector struct {
config Config config Config
perfDataCollector *perfdata.Collector perfDataCollector perfdata.Collector
processorRTCValues map[string]cpuCounter processorRTCValues map[string]cpuCounter
processorMPerfValues map[string]cpuCounter processorMPerfValues map[string]cpuCounter
@@ -113,7 +113,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
var err error var err error
c.perfDataCollector, err = perfdata.NewCollector("Processor Information", []string{"*"}, counters) c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Processor Information", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create Processor Information collector: %w", err) return fmt.Errorf("failed to create Processor Information collector: %w", err)
} }
@@ -248,7 +248,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
func (c *Collector) collectFull(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collectFull(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
data := make([]perflibProcessorInformation, 0) data := make([]perflibProcessorInformation, 0)
err := perflib.UnmarshalObject(ctx.PerfObjects["Processor Information"], &data, logger) err := v1.UnmarshalObject(ctx.PerfObjects["Processor Information"], &data, logger)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -11,7 +11,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -32,9 +32,9 @@ var ConfigDefaults = Config{
type Collector struct { type Collector struct {
config Config config Config
perfDataCollectorConnection *perfdata.Collector perfDataCollectorConnection perfdata.Collector
perfDataCollectorFolder *perfdata.Collector perfDataCollectorFolder perfdata.Collector
perfDataCollectorVolume *perfdata.Collector perfDataCollectorVolume perfdata.Collector
// connection source // connection source
connectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc connectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
@@ -189,7 +189,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
sizeOfFilesReceivedTotal, sizeOfFilesReceivedTotal,
} }
c.perfDataCollectorConnection, err = perfdata.NewCollector("DFS Replication Connections", []string{"*"}, counters) c.perfDataCollectorConnection, err = perfdata.NewCollector(perfdata.V1, "DFS Replication Connections", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create Replication Connections collector: %w", err) return fmt.Errorf("failed to create Replication Connections collector: %w", err)
} }
@@ -226,7 +226,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
updatesDroppedTotal, updatesDroppedTotal,
} }
c.perfDataCollectorFolder, err = perfdata.NewCollector("DFS Replicated Folders", []string{"*"}, counters) c.perfDataCollectorFolder, err = perfdata.NewCollector(perfdata.V1, "DFS Replicated Folders", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create Replication Connections collector: %w", err) return fmt.Errorf("failed to create Replication Connections collector: %w", err)
} }
@@ -241,7 +241,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
usnJournalUnreadPercentage, usnJournalUnreadPercentage,
} }
c.perfDataCollectorVolume, err = perfdata.NewCollector("DFS Replication Service Volumes", []string{"*"}, counters) c.perfDataCollectorVolume, err = perfdata.NewCollector(perfdata.V1, "DFS Replication Service Volumes", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create Replication Connections collector: %w", err) return fmt.Errorf("failed to create Replication Connections collector: %w", err)
} }
@@ -585,7 +585,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
func (c *Collector) collectConnection(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collectConnection(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []PerflibDFSRConnection var dst []PerflibDFSRConnection
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Connections"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["DFS Replication Connections"], &dst, logger); err != nil {
return err return err
} }
@@ -660,7 +660,7 @@ func (c *Collector) collectConnection(ctx *types.ScrapeContext, logger *slog.Log
func (c *Collector) collectFolder(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collectFolder(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []perflibDFSRFolder var dst []perflibDFSRFolder
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replicated Folders"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["DFS Replicated Folders"], &dst, logger); err != nil {
return err return err
} }
@@ -861,7 +861,7 @@ func (c *Collector) collectFolder(ctx *types.ScrapeContext, logger *slog.Logger,
func (c *Collector) collectVolume(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collectVolume(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []perflibDFSRVolume var dst []perflibDFSRVolume
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Service Volumes"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["DFS Replication Service Volumes"], &dst, logger); err != nil {
return err return err
} }

View File

@@ -6,7 +6,7 @@ import (
"log/slog" "log/slog"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -268,7 +268,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
var dhcpPerfs []dhcpPerf var dhcpPerfs []dhcpPerf
if err := perflib.UnmarshalObject(ctx.PerfObjects["DHCP Server"], &dhcpPerfs, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["DHCP Server"], &dhcpPerfs, logger); err != nil {
return err return err
} }

View File

@@ -9,7 +9,7 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -275,7 +275,7 @@ func (c *Collector) collectADAccessProcesses(ctx *types.ScrapeContext, logger *s
var data []perflibADAccessProcesses var data []perflibADAccessProcesses
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange ADAccess Processes"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange ADAccess Processes"], &data, logger); err != nil {
return err return err
} }
@@ -338,7 +338,7 @@ func (c *Collector) collectAvailabilityService(ctx *types.ScrapeContext, logger
var data []perflibAvailabilityService var data []perflibAvailabilityService
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange Availability Service"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange Availability Service"], &data, logger); err != nil {
return err return err
} }
@@ -370,7 +370,7 @@ func (c *Collector) collectHTTPProxy(ctx *types.ScrapeContext, logger *slog.Logg
var data []perflibHTTPProxy var data []perflibHTTPProxy
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange HttpProxy"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange HttpProxy"], &data, logger); err != nil {
return err return err
} }
@@ -428,7 +428,7 @@ func (c *Collector) collectOWA(ctx *types.ScrapeContext, logger *slog.Logger, ch
var data []perflibOWA var data []perflibOWA
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange OWA"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange OWA"], &data, logger); err != nil {
return err return err
} }
@@ -460,7 +460,7 @@ func (c *Collector) collectActiveSync(ctx *types.ScrapeContext, logger *slog.Log
var data []perflibActiveSync var data []perflibActiveSync
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange ActiveSync"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange ActiveSync"], &data, logger); err != nil {
return err return err
} }
@@ -500,7 +500,7 @@ func (c *Collector) collectRPC(ctx *types.ScrapeContext, logger *slog.Logger, ch
var data []perflibRPCClientAccess var data []perflibRPCClientAccess
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange RpcClientAccess"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange RpcClientAccess"], &data, logger); err != nil {
return err return err
} }
@@ -559,7 +559,7 @@ func (c *Collector) collectTransportQueues(ctx *types.ScrapeContext, logger *slo
var data []perflibTransportQueues var data []perflibTransportQueues
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchangeTransport Queues"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchangeTransport Queues"], &data, logger); err != nil {
return err return err
} }
@@ -637,7 +637,7 @@ func (c *Collector) collectWorkloadManagementWorkloads(ctx *types.ScrapeContext,
var data []perflibWorkloadManagementWorkloads var data []perflibWorkloadManagementWorkloads
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange WorkloadManagement Workloads"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange WorkloadManagement Workloads"], &data, logger); err != nil {
return err return err
} }
@@ -691,7 +691,7 @@ func (c *Collector) collectAutoDiscover(ctx *types.ScrapeContext, logger *slog.L
var data []perflibAutodiscover var data []perflibAutodiscover
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchangeAutodiscover"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchangeAutodiscover"], &data, logger); err != nil {
return err return err
} }
@@ -716,7 +716,7 @@ func (c *Collector) collectMapiHttpEmsmdb(ctx *types.ScrapeContext, logger *slog
var data []perflibMapiHttpEmsmdb var data []perflibMapiHttpEmsmdb
if err := perflib.UnmarshalObject(ctx.PerfObjects["MSExchange MapiHttp Emsmdb"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange MapiHttp Emsmdb"], &data, logger); err != nil {
return err return err
} }

View File

@@ -10,7 +10,7 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -1073,7 +1073,7 @@ func (c *Collector) collectWebService(ctx *types.ScrapeContext, logger *slog.Log
var webService []perflibWebService var webService []perflibWebService
if err := perflib.UnmarshalObject(ctx.PerfObjects["Web Service"], &webService, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["Web Service"], &webService, logger); err != nil {
return err return err
} }
@@ -1368,7 +1368,7 @@ func (c *Collector) collectAPP_POOL_WAS(ctx *types.ScrapeContext, logger *slog.L
var APP_POOL_WAS []perflibAPP_POOL_WAS var APP_POOL_WAS []perflibAPP_POOL_WAS
if err := perflib.UnmarshalObject(ctx.PerfObjects["APP_POOL_WAS"], &APP_POOL_WAS, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["APP_POOL_WAS"], &APP_POOL_WAS, logger); err != nil {
return err return err
} }
@@ -1548,7 +1548,7 @@ func (c *Collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, logger *slog.Log
var W3SVC_W3WP []perflibW3SVC_W3WP var W3SVC_W3WP []perflibW3SVC_W3WP
if err := perflib.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP, logger); err != nil {
return err return err
} }
@@ -1807,7 +1807,7 @@ func (c *Collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, logger *slog.Log
if c.iisVersion.major >= 8 { if c.iisVersion.major >= 8 {
var W3SVC_W3WP_IIS8 []perflibW3SVC_W3WP_IIS8 var W3SVC_W3WP_IIS8 []perflibW3SVC_W3WP_IIS8
if err := perflib.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP_IIS8, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP_IIS8, logger); err != nil {
return err return err
} }
@@ -1950,7 +1950,7 @@ func (c *Collector) collectWebServiceCache(ctx *types.ScrapeContext, logger *slo
var WebServiceCache []perflibWebServiceCache var WebServiceCache []perflibWebServiceCache
if err := perflib.UnmarshalObject(ctx.PerfObjects["Web Service Cache"], &WebServiceCache, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["Web Service Cache"], &WebServiceCache, logger); err != nil {
return err return err
} }

View File

@@ -12,7 +12,8 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -307,7 +308,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
dst []logicalDisk dst []logicalDisk
) )
if err = perflib.UnmarshalObject(ctx.PerfObjects["LogicalDisk"], &dst, logger); err != nil { if err = v1.UnmarshalObject(ctx.PerfObjects["LogicalDisk"], &dst, logger); err != nil {
return err return err
} }
@@ -354,14 +355,14 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.avgReadQueue, c.avgReadQueue,
prometheus.GaugeValue, prometheus.GaugeValue,
volume.AvgDiskReadQueueLength*perflib.TicksToSecondScaleFactor, volume.AvgDiskReadQueueLength*perftypes.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.avgWriteQueue, c.avgWriteQueue,
prometheus.GaugeValue, prometheus.GaugeValue,
volume.AvgDiskWriteQueueLength*perflib.TicksToSecondScaleFactor, volume.AvgDiskWriteQueueLength*perftypes.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) )
@@ -438,21 +439,21 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.readLatency, c.readLatency,
prometheus.CounterValue, prometheus.CounterValue,
volume.AvgDiskSecPerRead*perflib.TicksToSecondScaleFactor, volume.AvgDiskSecPerRead*perftypes.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.writeLatency, c.writeLatency,
prometheus.CounterValue, prometheus.CounterValue,
volume.AvgDiskSecPerWrite*perflib.TicksToSecondScaleFactor, volume.AvgDiskSecPerWrite*perftypes.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.readWriteLatency, c.readWriteLatency,
prometheus.CounterValue, prometheus.CounterValue,
volume.AvgDiskSecPerTransfer*perflib.TicksToSecondScaleFactor, volume.AvgDiskSecPerTransfer*perftypes.TicksToSecondScaleFactor,
volume.Name, volume.Name,
) )
} }

View File

@@ -12,7 +12,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi" "github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -418,7 +418,7 @@ func (c *Collector) collectPerformanceData(ctx *types.ScrapeContext, logger *slo
var dst []memory var dst []memory
if err := perflib.UnmarshalObject(ctx.PerfObjects["Memory"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["Memory"], &dst, logger); err != nil {
return err return err
} }

View File

@@ -13,7 +13,7 @@ import (
"time" "time"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -2104,7 +2104,7 @@ func (c *Collector) collectAccessMethods(ctx *types.ScrapeContext, logger *slog.
logger.Debug(fmt.Sprintf("mssql_accessmethods collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_accessmethods collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "accessmethods")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "accessmethods")], &dst, logger); err != nil {
return err return err
} }
@@ -2441,7 +2441,7 @@ func (c *Collector) collectAvailabilityReplica(ctx *types.ScrapeContext, logger
logger.Debug(fmt.Sprintf("mssql_availreplica collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_availreplica collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "availreplica")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "availreplica")], &dst, logger); err != nil {
return err return err
} }
@@ -2552,7 +2552,7 @@ func (c *Collector) collectBufferManager(ctx *types.ScrapeContext, logger *slog.
logger.Debug(fmt.Sprintf("mssql_bufman collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_bufman collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "bufman")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "bufman")], &dst, logger); err != nil {
return err return err
} }
@@ -2757,7 +2757,7 @@ func (c *Collector) collectDatabaseReplica(ctx *types.ScrapeContext, logger *slo
logger.Debug(fmt.Sprintf("mssql_dbreplica collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_dbreplica collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "dbreplica")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "dbreplica")], &dst, logger); err != nil {
return err return err
} }
@@ -2999,7 +2999,7 @@ func (c *Collector) collectDatabases(ctx *types.ScrapeContext, logger *slog.Logg
logger.Debug(fmt.Sprintf("mssql_databases collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_databases collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "databases")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "databases")], &dst, logger); err != nil {
return err return err
} }
@@ -3384,7 +3384,7 @@ func (c *Collector) collectGeneralStatistics(ctx *types.ScrapeContext, logger *s
logger.Debug(fmt.Sprintf("mssql_genstats collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_genstats collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "genstats")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "genstats")], &dst, logger); err != nil {
return err return err
} }
@@ -3580,7 +3580,7 @@ func (c *Collector) collectLocks(ctx *types.ScrapeContext, logger *slog.Logger,
logger.Debug(fmt.Sprintf("mssql_locks collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_locks collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "locks")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "locks")], &dst, logger); err != nil {
return err return err
} }
@@ -3681,7 +3681,7 @@ func (c *Collector) collectMemoryManager(ctx *types.ScrapeContext, logger *slog.
logger.Debug(fmt.Sprintf("mssql_memmgr collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_memmgr collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "memmgr")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "memmgr")], &dst, logger); err != nil {
return err return err
} }
@@ -3851,7 +3851,7 @@ func (c *Collector) collectSQLStats(ctx *types.ScrapeContext, logger *slog.Logge
logger.Debug(fmt.Sprintf("mssql_sqlstats collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_sqlstats collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlstats")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlstats")], &dst, logger); err != nil {
return err return err
} }
@@ -3960,7 +3960,7 @@ func (c *Collector) collectWaitStats(ctx *types.ScrapeContext, logger *slog.Logg
logger.Debug(fmt.Sprintf("mssql_waitstats collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_waitstats collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "waitstats")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "waitstats")], &dst, logger); err != nil {
return err return err
} }
@@ -4067,7 +4067,7 @@ func (c *Collector) collectSQLErrors(ctx *types.ScrapeContext, logger *slog.Logg
logger.Debug(fmt.Sprintf("mssql_sqlerrors collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_sqlerrors collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlerrors")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlerrors")], &dst, logger); err != nil {
return err return err
} }
@@ -4112,7 +4112,7 @@ func (c *Collector) collectTransactions(ctx *types.ScrapeContext, logger *slog.L
logger.Debug(fmt.Sprintf("mssql_transactions collector iterating sql instance %s.", sqlInstance)) logger.Debug(fmt.Sprintf("mssql_transactions collector iterating sql instance %s.", sqlInstance))
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "transactions")], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "transactions")], &dst, logger); err != nil {
return err return err
} }

View File

@@ -14,7 +14,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -43,7 +43,7 @@ var ConfigDefaults = Config{
type Collector struct { type Collector struct {
config Config config Config
perfDataCollector *perfdata.Collector perfDataCollector perfdata.Collector
bytesReceivedTotal *prometheus.Desc bytesReceivedTotal *prometheus.Desc
bytesSentTotal *prometheus.Desc bytesSentTotal *prometheus.Desc
@@ -169,7 +169,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
var err error var err error
c.perfDataCollector, err = perfdata.NewCollector("Network Interface", []string{"*"}, counters) c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Network Interface", perfdata.AllInstances, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create Processor Information collector: %w", err) return fmt.Errorf("failed to create Processor Information collector: %w", err)
} }
@@ -306,7 +306,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
var dst []perflibNetworkInterface var dst []perflibNetworkInterface
if err := perflib.UnmarshalObject(ctx.PerfObjects["Network Interface"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["Network Interface"], &dst, logger); err != nil {
return err return err
} }

View File

@@ -16,7 +16,7 @@ import (
"github.com/prometheus-community/windows_exporter/internal/headers/netapi32" "github.com/prometheus-community/windows_exporter/internal/headers/netapi32"
"github.com/prometheus-community/windows_exporter/internal/headers/psapi" "github.com/prometheus-community/windows_exporter/internal/headers/psapi"
"github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi" "github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -412,7 +412,7 @@ func (c *Collector) collectPaging(ctx *types.ScrapeContext, logger *slog.Logger,
} }
pfc := make([]pagingFileCounter, 0) pfc := make([]pagingFileCounter, 0)
if err = perflib.UnmarshalObject(ctx.PerfObjects["Paging File"], &pfc, logger); err != nil { if err = v1.UnmarshalObject(ctx.PerfObjects["Paging File"], &pfc, logger); err != nil {
return err return err
} }

View File

@@ -12,14 +12,13 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
) )
const ( const Name = "perfdata"
Name = "perfdata"
)
type Config struct { type Config struct {
Objects []Object `yaml:"objects"` Objects []Object `yaml:"objects"`
@@ -97,9 +96,9 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
logger.Warn("The perfdata collector is in an experimental state! The configuration may change in future. Please report any issues.") logger.Warn("The perfdata collector is in an experimental state! The configuration may change in future. Please report any issues.")
for i, object := range c.config.Objects { for i, object := range c.config.Objects {
collector, err := perfdata.NewCollector(object.Object, object.Instances, slices.Sorted(maps.Keys(object.Counters))) collector, err := perfdata.NewCollector(perfdata.V2, object.Object, object.Instances, slices.Sorted(maps.Keys(object.Counters)))
if err != nil { if err != nil {
return fmt.Errorf("failed to create pdh collector: %w", err) return fmt.Errorf("failed to create v2 collector: %w", err)
} }
if object.InstanceLabel == "" { if object.InstanceLabel == "" {
@@ -136,7 +135,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
for instance, counters := range data { for instance, counters := range data {
for counter, value := range counters { for counter, value := range counters {
var labels prometheus.Labels var labels prometheus.Labels
if instance != perfdata.EmptyInstance { if instance != perftypes.EmptyInstance {
labels = prometheus.Labels{object.InstanceLabel: instance} labels = prometheus.Labels{object.InstanceLabel: instance}
} }

View File

@@ -1,8 +1,6 @@
package perfdata package perfdata
import ( import "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perfdata"
)
type Object struct { type Object struct {
Object string `json:"object" yaml:"object"` Object string `json:"object" yaml:"object"`
@@ -10,7 +8,7 @@ type Object struct {
Counters map[string]Counter `json:"counters" yaml:"counters"` Counters map[string]Counter `json:"counters" yaml:"counters"`
InstanceLabel string `json:"instance_label" yaml:"instance_label"` //nolint:tagliatelle InstanceLabel string `json:"instance_label" yaml:"instance_label"` //nolint:tagliatelle
collector *perfdata.Collector collector perfdata.Collector
} }
type Counter struct { type Counter struct {

View File

@@ -9,7 +9,8 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -240,7 +241,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
var dst []PhysicalDisk var dst []PhysicalDisk
if err := perflib.UnmarshalObject(ctx.PerfObjects["PhysicalDisk"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["PhysicalDisk"], &dst, logger); err != nil {
return err return err
} }
@@ -321,21 +322,21 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.readLatency, c.readLatency,
prometheus.CounterValue, prometheus.CounterValue,
disk.AvgDiskSecPerRead*perflib.TicksToSecondScaleFactor, disk.AvgDiskSecPerRead*perftypes.TicksToSecondScaleFactor,
disk_number, disk_number,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.writeLatency, c.writeLatency,
prometheus.CounterValue, prometheus.CounterValue,
disk.AvgDiskSecPerWrite*perflib.TicksToSecondScaleFactor, disk.AvgDiskSecPerWrite*perftypes.TicksToSecondScaleFactor,
disk_number, disk_number,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.readWriteLatency, c.readWriteLatency,
prometheus.CounterValue, prometheus.CounterValue,
disk.AvgDiskSecPerTransfer*perflib.TicksToSecondScaleFactor, disk.AvgDiskSecPerTransfer*perftypes.TicksToSecondScaleFactor,
disk_number, disk_number,
) )
} }

View File

@@ -13,7 +13,8 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
v2 "github.com/prometheus-community/windows_exporter/internal/perfdata/v2"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -24,24 +25,22 @@ import (
const Name = "process" const Name = "process"
type Config struct { type Config struct {
ProcessInclude *regexp.Regexp `yaml:"process_include"` ProcessInclude *regexp.Regexp `yaml:"process_include"`
ProcessExclude *regexp.Regexp `yaml:"process_exclude"` ProcessExclude *regexp.Regexp `yaml:"process_exclude"`
EnableWorkerProcess bool `yaml:"enable_iis_worker_process"` //nolint:tagliatelle EnableWorkerProcess bool `yaml:"enable_iis_worker_process"` //nolint:tagliatelle
PerfCounterInstances []string `yaml:"perf_counter_instances"`
} }
var ConfigDefaults = Config{ var ConfigDefaults = Config{
ProcessInclude: types.RegExpAny, ProcessInclude: types.RegExpAny,
ProcessExclude: types.RegExpEmpty, ProcessExclude: types.RegExpEmpty,
EnableWorkerProcess: false, EnableWorkerProcess: false,
PerfCounterInstances: []string{"*"},
} }
type Collector struct { type Collector struct {
config Config config Config
wmiClient *wmi.Client wmiClient *wmi.Client
perfDataCollector *perfdata.Collector perfDataCollector perfdata.Collector
lookupCache map[string]string lookupCache map[string]string
@@ -76,10 +75,6 @@ func New(config *Config) *Collector {
config.ProcessInclude = ConfigDefaults.ProcessInclude config.ProcessInclude = ConfigDefaults.ProcessInclude
} }
if config.PerfCounterInstances == nil {
config.PerfCounterInstances = ConfigDefaults.PerfCounterInstances
}
c := &Collector{ c := &Collector{
config: *config, config: *config,
} }
@@ -92,7 +87,7 @@ func NewWithFlags(app *kingpin.Application) *Collector {
config: ConfigDefaults, config: ConfigDefaults,
} }
var processExclude, processInclude, perfCounterInstances string var processExclude, processInclude string
app.Flag( app.Flag(
"collector.process.exclude", "collector.process.exclude",
@@ -109,14 +104,7 @@ func NewWithFlags(app *kingpin.Application) *Collector {
"Enable IIS worker process name queries. May cause the collector to leak memory.", "Enable IIS worker process name queries. May cause the collector to leak memory.",
).Default(strconv.FormatBool(c.config.EnableWorkerProcess)).BoolVar(&c.config.EnableWorkerProcess) ).Default(strconv.FormatBool(c.config.EnableWorkerProcess)).BoolVar(&c.config.EnableWorkerProcess)
app.Flag(
"collector.process.perf-counter-instance",
"Advanced: List of process performance counter instances to query. If not set, all instances are queried.",
).Default(strings.Join(c.config.PerfCounterInstances, ",")).StringVar(&perfCounterInstances)
app.Action(func(*kingpin.ParseContext) error { app.Action(func(*kingpin.ParseContext) error {
c.config.PerfCounterInstances = strings.Split(perfCounterInstances, ",")
var err error var err error
c.config.ProcessExclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", processExclude)) c.config.ProcessExclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", processExclude))
@@ -194,11 +182,11 @@ func (c *Collector) Build(logger *slog.Logger, wmiClient *wmi.Client) error {
var err error var err error
c.perfDataCollector, err = perfdata.NewCollector("Process V2", c.config.PerfCounterInstances, counters) c.perfDataCollector, err = perfdata.NewCollector(perfdata.V2, "Process V2", perfdata.AllInstances, counters)
if errors.Is(err, perfdata.NewPdhError(perfdata.PdhCstatusNoObject)) { if errors.Is(err, v2.NewPdhError(v2.PdhCstatusNoObject)) {
counters[0] = idProcess counters[0] = idProcess
c.perfDataCollector, err = perfdata.NewCollector("Process", c.config.PerfCounterInstances, counters) c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Process", perfdata.AllInstances, counters)
} }
if err != nil { if err != nil {
@@ -338,7 +326,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
data := make([]perflibProcess, 0) data := make([]perflibProcess, 0)
err := perflib.UnmarshalObject(ctx.PerfObjects["Process"], &data, logger) err := v1.UnmarshalObject(ctx.PerfObjects["Process"], &data, logger)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -7,7 +7,7 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -253,7 +253,7 @@ func (c *Collector) collectRemoteFXNetworkCount(ctx *types.ScrapeContext, logger
logger = logger.With(slog.String("collector", Name)) logger = logger.With(slog.String("collector", Name))
dst := make([]perflibRemoteFxNetwork, 0) dst := make([]perflibRemoteFxNetwork, 0)
err := perflib.UnmarshalObject(ctx.PerfObjects["RemoteFX Network"], &dst, logger) err := v1.UnmarshalObject(ctx.PerfObjects["RemoteFX Network"], &dst, logger)
if err != nil { if err != nil {
return err return err
} }
@@ -366,7 +366,7 @@ func (c *Collector) collectRemoteFXGraphicsCounters(ctx *types.ScrapeContext, lo
logger = logger.With(slog.String("collector", Name)) logger = logger.With(slog.String("collector", Name))
dst := make([]perflibRemoteFxGraphics, 0) dst := make([]perflibRemoteFxGraphics, 0)
err := perflib.UnmarshalObject(ctx.PerfObjects["RemoteFX Graphics"], &dst, logger) err := v1.UnmarshalObject(ctx.PerfObjects["RemoteFX Graphics"], &dst, logger)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -7,7 +7,7 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -100,7 +100,7 @@ func (c *Collector) collectServerShares(ctx *types.ScrapeContext, logger *slog.L
var data []perflibServerShares var data []perflibServerShares
if err := perflib.UnmarshalObject(ctx.PerfObjects["SMB Server Shares"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["SMB Server Shares"], &data, logger); err != nil {
return err return err
} }

View File

@@ -7,7 +7,8 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -223,7 +224,7 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L
var data []perflibClientShares var data []perflibClientShares
if err := perflib.UnmarshalObject(ctx.PerfObjects["SMB Client Shares"], &data, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["SMB Client Shares"], &data, logger); err != nil {
return err return err
} }
@@ -239,7 +240,7 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.requestQueueSecsTotal, c.requestQueueSecsTotal,
prometheus.CounterValue, prometheus.CounterValue,
instance.AvgDataQueueLength*perflib.TicksToSecondScaleFactor, instance.AvgDataQueueLength*perftypes.TicksToSecondScaleFactor,
serverValue, shareValue, serverValue, shareValue,
) )
@@ -247,28 +248,28 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.readRequestQueueSecsTotal, c.readRequestQueueSecsTotal,
prometheus.CounterValue, prometheus.CounterValue,
instance.AvgReadQueueLength*perflib.TicksToSecondScaleFactor, instance.AvgReadQueueLength*perftypes.TicksToSecondScaleFactor,
serverValue, shareValue, serverValue, shareValue,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.readSecsTotal, c.readSecsTotal,
prometheus.CounterValue, prometheus.CounterValue,
instance.AvgSecPerRead*perflib.TicksToSecondScaleFactor, instance.AvgSecPerRead*perftypes.TicksToSecondScaleFactor,
serverValue, shareValue, serverValue, shareValue,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.writeSecsTotal, c.writeSecsTotal,
prometheus.CounterValue, prometheus.CounterValue,
instance.AvgSecPerWrite*perflib.TicksToSecondScaleFactor, instance.AvgSecPerWrite*perftypes.TicksToSecondScaleFactor,
serverValue, shareValue, serverValue, shareValue,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.requestSecs, c.requestSecs,
prometheus.CounterValue, prometheus.CounterValue,
instance.AvgSecPerDataRequest*perflib.TicksToSecondScaleFactor, instance.AvgSecPerDataRequest*perftypes.TicksToSecondScaleFactor,
serverValue, shareValue, serverValue, shareValue,
) )
@@ -276,7 +277,7 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.writeRequestQueueSecsTotal, c.writeRequestQueueSecsTotal,
prometheus.CounterValue, prometheus.CounterValue,
instance.AvgWriteQueueLength*perflib.TicksToSecondScaleFactor, instance.AvgWriteQueueLength*perftypes.TicksToSecondScaleFactor,
serverValue, shareValue, serverValue, shareValue,
) )

View File

@@ -8,7 +8,7 @@ import (
"regexp" "regexp"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -470,7 +470,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
var dst []PerflibSMTPServer var dst []PerflibSMTPServer
if err := perflib.UnmarshalObject(ctx.PerfObjects["SMTP Server"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["SMTP Server"], &dst, logger); err != nil {
return err return err
} }

View File

@@ -7,7 +7,7 @@ import (
"log/slog" "log/slog"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -147,7 +147,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch
var dst []system var dst []system
if err := perflib.UnmarshalObject(ctx.PerfObjects["System"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["System"], &dst, logger); err != nil {
return err return err
} }

View File

@@ -11,6 +11,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/headers/iphlpapi" "github.com/prometheus-community/windows_exporter/internal/headers/iphlpapi"
"github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -34,8 +35,8 @@ var ConfigDefaults = Config{
type Collector struct { type Collector struct {
config Config config Config
perfDataCollector4 *perfdata.Collector perfDataCollector4 perfdata.Collector
perfDataCollector6 *perfdata.Collector perfDataCollector6 perfdata.Collector
connectionFailures *prometheus.Desc connectionFailures *prometheus.Desc
connectionsActive *prometheus.Desc connectionsActive *prometheus.Desc
@@ -114,12 +115,12 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
var err error var err error
c.perfDataCollector4, err = perfdata.NewCollector("TCPv4", nil, counters) c.perfDataCollector4, err = perfdata.NewCollector(perfdata.V1, "TCPv4", nil, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create TCPv4 collector: %w", err) return fmt.Errorf("failed to create TCPv4 collector: %w", err)
} }
c.perfDataCollector6, err = perfdata.NewCollector("TCPv6", nil, counters) c.perfDataCollector6, err = perfdata.NewCollector(perfdata.V1, "TCPv6", nil, counters)
if err != nil { if err != nil {
return fmt.Errorf("failed to create TCPv6 collector: %w", err) return fmt.Errorf("failed to create TCPv6 collector: %w", err)
} }
@@ -221,19 +222,19 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
return fmt.Errorf("failed to collect TCPv4 metrics: %w", err) return fmt.Errorf("failed to collect TCPv4 metrics: %w", err)
} }
c.writeTCPCounters(ch, data[perfdata.EmptyInstance], []string{"ipv4"}) c.writeTCPCounters(ch, data[perftypes.EmptyInstance], []string{"ipv4"})
data, err = c.perfDataCollector6.Collect() data, err = c.perfDataCollector6.Collect()
if err != nil { if err != nil {
return fmt.Errorf("failed to collect TCPv6 metrics: %w", err) return fmt.Errorf("failed to collect TCPv6 metrics: %w", err)
} }
c.writeTCPCounters(ch, data[perfdata.EmptyInstance], []string{"ipv6"}) c.writeTCPCounters(ch, data[perftypes.EmptyInstance], []string{"ipv6"})
return nil return nil
} }
func (c *Collector) writeTCPCounters(ch chan<- prometheus.Metric, metrics map[string]perfdata.CounterValues, labels []string) { func (c *Collector) writeTCPCounters(ch chan<- prometheus.Metric, metrics map[string]perftypes.CounterValues, labels []string) {
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.connectionFailures, c.connectionFailures,
prometheus.CounterValue, prometheus.CounterValue,

View File

@@ -11,7 +11,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/headers/wtsapi32" "github.com/prometheus-community/windows_exporter/internal/headers/wtsapi32"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -275,7 +275,7 @@ func (c *Collector) collectTSSessionCounters(ctx *types.ScrapeContext, logger *s
logger = logger.With(slog.String("collector", Name)) logger = logger.With(slog.String("collector", Name))
dst := make([]perflibTerminalServicesSession, 0) dst := make([]perflibTerminalServicesSession, 0)
err := perflib.UnmarshalObject(ctx.PerfObjects["Terminal Services Session"], &dst, logger) err := v1.UnmarshalObject(ctx.PerfObjects["Terminal Services Session"], &dst, logger)
if err != nil { if err != nil {
return err return err
} }
@@ -403,7 +403,7 @@ func (c *Collector) collectCollectionBrokerPerformanceCounter(ctx *types.ScrapeC
logger = logger.With(slog.String("collector", Name)) logger = logger.With(slog.String("collector", Name))
dst := make([]perflibRemoteDesktopConnectionBrokerCounterset, 0) dst := make([]perflibRemoteDesktopConnectionBrokerCounterset, 0)
err := perflib.UnmarshalObject(ctx.PerfObjects["Remote Desktop Connection Broker Counterset"], &dst, logger) err := v1.UnmarshalObject(ctx.PerfObjects["Remote Desktop Connection Broker Counterset"], &dst, logger)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -9,7 +9,7 @@ import (
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/headers/kernel32" "github.com/prometheus-community/windows_exporter/internal/headers/kernel32"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -183,7 +183,7 @@ func (c *Collector) collectNTP(ctx *types.ScrapeContext, logger *slog.Logger, ch
var dst []windowsTime // Single-instance class, array is required but will have single entry. var dst []windowsTime // Single-instance class, array is required but will have single entry.
if err := perflib.UnmarshalObject(ctx.PerfObjects["Windows Time Service"], &dst, logger); err != nil { if err := v1.UnmarshalObject(ctx.PerfObjects["Windows Time Service"], &dst, logger); err != nil {
return err return err
} }

View File

@@ -7,7 +7,7 @@ import (
"log/slog" "log/slog"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/perflib" "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
@@ -368,13 +368,13 @@ func (c *Collector) collectCpu(ch chan<- prometheus.Metric) error {
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.cpuStolenTotal, c.cpuStolenTotal,
prometheus.CounterValue, prometheus.CounterValue,
float64(dst[0].CpuStolenMs)*perflib.TicksToSecondScaleFactor, float64(dst[0].CpuStolenMs)*perftypes.TicksToSecondScaleFactor,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.cpuTimeTotal, c.cpuTimeTotal,
prometheus.CounterValue, prometheus.CounterValue,
float64(dst[0].CpuTimePercents)*perflib.TicksToSecondScaleFactor, float64(dst[0].CpuTimePercents)*perftypes.TicksToSecondScaleFactor,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(

View File

@@ -0,0 +1,40 @@
package perfdata
import (
"errors"
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
v2 "github.com/prometheus-community/windows_exporter/internal/perfdata/v2"
)
type Collector interface {
Describe() map[string]string
Collect() (map[string]map[string]perftypes.CounterValues, error)
Close()
}
type Engine int
const (
_ Engine = iota
V1
V2
)
var (
ErrUnknownEngine = errors.New("unknown engine")
AllInstances = []string{"*"}
)
//nolint:ireturn
func NewCollector(engine Engine, object string, instances []string, counters []string) (Collector, error) {
switch engine {
case V1:
return v1.NewCollector(object, instances, counters)
case V2:
return v2.NewCollector(object, instances, counters)
default:
return nil, ErrUnknownEngine
}
}

View File

@@ -1,6 +1,4 @@
//go:build windows package perftypes
package perfdata
import "github.com/prometheus/client_golang/prometheus" import "github.com/prometheus/client_golang/prometheus"
@@ -57,7 +55,7 @@ const (
PERF_COUNTER_HISTOGRAM_TYPE = 0x80000000 PERF_COUNTER_HISTOGRAM_TYPE = 0x80000000
) )
var supportedCounterTypes = map[uint32]prometheus.ValueType{ var SupportedCounterTypes = map[uint32]prometheus.ValueType{
PERF_COUNTER_RAWCOUNT_HEX: prometheus.GaugeValue, PERF_COUNTER_RAWCOUNT_HEX: prometheus.GaugeValue,
PERF_COUNTER_LARGE_RAWCOUNT_HEX: prometheus.GaugeValue, PERF_COUNTER_LARGE_RAWCOUNT_HEX: prometheus.GaugeValue,
PERF_COUNTER_RAWCOUNT: prometheus.GaugeValue, PERF_COUNTER_RAWCOUNT: prometheus.GaugeValue,

View File

@@ -0,0 +1,11 @@
package perftypes
import "github.com/prometheus/client_golang/prometheus"
const EmptyInstance = "------"
type CounterValues struct {
Type prometheus.ValueType
FirstValue float64
SecondValue float64
}

View File

@@ -0,0 +1,98 @@
package v1
import (
"fmt"
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
"github.com/prometheus/client_golang/prometheus"
)
type Collector struct {
object string
query string
}
type Counter struct {
Name string
Desc string
Instances map[string]uint32
Type uint32
Frequency float64
}
func NewCollector(object string, _ []string, _ []string) (*Collector, error) {
collector := &Collector{
object: object,
query: MapCounterToIndex(object),
}
if _, err := collector.Collect(); err != nil {
return nil, fmt.Errorf("failed to collect initial data: %w", err)
}
return collector, nil
}
func (c *Collector) Describe() map[string]string {
return map[string]string{}
}
func (c *Collector) Collect() (map[string]map[string]perftypes.CounterValues, error) {
perfObjects, err := QueryPerformanceData(c.query)
if err != nil {
return nil, fmt.Errorf("QueryPerformanceData: %w", err)
}
data := make(map[string]map[string]perftypes.CounterValues, len(perfObjects[0].Instances))
for _, perfObject := range perfObjects {
for _, perfInstance := range perfObject.Instances {
instanceName := perfInstance.Name
if instanceName == "" || instanceName == "*" {
instanceName = perftypes.EmptyInstance
}
if _, ok := data[instanceName]; !ok {
data[instanceName] = make(map[string]perftypes.CounterValues, len(perfInstance.Counters))
}
for _, perfCounter := range perfInstance.Counters {
if _, ok := data[instanceName][perfCounter.Def.Name]; !ok {
data[instanceName][perfCounter.Def.Name] = perftypes.CounterValues{
Type: prometheus.GaugeValue,
}
}
var metricType prometheus.ValueType
if val, ok := perftypes.SupportedCounterTypes[perfCounter.Def.CounterType]; ok {
metricType = val
} else {
metricType = prometheus.GaugeValue
}
values := perftypes.CounterValues{
Type: metricType,
}
switch perfCounter.Def.CounterType {
case perftypes.PERF_ELAPSED_TIME:
values.FirstValue = float64(perfCounter.Value-perftypes.WindowsEpoch) / float64(perfObject.Frequency)
values.SecondValue = float64(perfCounter.SecondValue-perftypes.WindowsEpoch) / float64(perfObject.Frequency)
case perftypes.PERF_100NSEC_TIMER, perftypes.PERF_PRECISION_100NS_TIMER:
values.FirstValue = float64(perfCounter.Value) * perftypes.TicksToSecondScaleFactor
values.SecondValue = float64(perfCounter.SecondValue) * perftypes.TicksToSecondScaleFactor
default:
values.FirstValue = float64(perfCounter.Value)
values.SecondValue = float64(perfCounter.SecondValue)
}
data[instanceName][perfCounter.Def.Name] = values
}
}
}
return data, nil
}
func (c *Collector) Close() {
}

View File

@@ -1,4 +1,4 @@
package perflib package v1
import ( import (
"bytes" "bytes"
@@ -41,7 +41,7 @@ func (t *NameTable) LookupIndex(str string) uint32 {
return t.table.string[str] return t.table.string[str]
} }
// QueryNameTable Query a perflib name table from the registry. Specify the type and the language // QueryNameTable Query a perflib name table from the v1. Specify the type and the language
// code (i.e. "Counter 009" or "Help 009") for English language. // code (i.e. "Counter 009" or "Help 009") for English language.
func QueryNameTable(tableName string) *NameTable { func QueryNameTable(tableName string) *NameTable {
return &NameTable{ return &NameTable{

View File

@@ -1,4 +1,4 @@
package perflib package v1
/* /*
Go bindings for the HKEY_PERFORMANCE_DATA perflib / Performance Counters interface. Go bindings for the HKEY_PERFORMANCE_DATA perflib / Performance Counters interface.
@@ -49,7 +49,7 @@ There's one counter per counter definition and instance (or the object itself, i
there are no instances). there are no instances).
Behind the scenes, every perflib DLL provides one or more objects. Behind the scenes, every perflib DLL provides one or more objects.
Perflib has a registry where DLLs are dynamically registered and Perflib has a v1 where DLLs are dynamically registered and
unregistered. Some third party applications like VMWare provide their own counters, unregistered. Some third party applications like VMWare provide their own counters,
but this is, sadly, a rare occurrence. but this is, sadly, a rare occurrence.
@@ -117,7 +117,6 @@ import (
"fmt" "fmt"
"io" "io"
"strings" "strings"
"syscall"
"unsafe" "unsafe"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
@@ -214,8 +213,7 @@ func queryRawData(query string) ([]byte, error) {
for { for {
bufLen := uint32(len(buffer)) bufLen := uint32(len(buffer))
//nolint:forbidigo // Legacy Code err := windows.RegQueryValueEx(
err := syscall.RegQueryValueEx(
windows.HKEY_PERFORMANCE_DATA, windows.HKEY_PERFORMANCE_DATA,
name, name,
nil, nil,
@@ -223,14 +221,14 @@ func queryRawData(query string) ([]byte, error) {
(*byte)(unsafe.Pointer(&buffer[0])), (*byte)(unsafe.Pointer(&buffer[0])),
&bufLen) &bufLen)
if errors.Is(err, error(syscall.ERROR_MORE_DATA)) { //nolint:forbidigo // Legacy Code if errors.Is(err, error(windows.ERROR_MORE_DATA)) {
newBuffer := make([]byte, len(buffer)+16384) newBuffer := make([]byte, len(buffer)+16384)
copy(newBuffer, buffer) copy(newBuffer, buffer)
buffer = newBuffer buffer = newBuffer
continue continue
} else if err != nil { } else if err != nil {
var errNo syscall.Errno //nolint:forbidigo // Legacy Code var errNo windows.Errno
if errors.As(err, &errNo) { if errors.As(err, &errNo) {
return nil, fmt.Errorf("ReqQueryValueEx failed: %w errno %d", err, uint(errNo)) return nil, fmt.Errorf("ReqQueryValueEx failed: %w errno %d", err, uint(errNo))
} }
@@ -446,8 +444,7 @@ func parseCounterBlock(b []byte, r io.ReadSeeker, pos int64, defs []*PerfCounter
return int64(block.ByteLength), counters, nil return int64(block.ByteLength), counters, nil
} }
//nolint:nonamedreturns func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, valueOffset int64) int64 {
func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, valueOffset int64) (value int64) {
/* /*
We can safely ignore the type since we're not interested in anything except the raw value. We can safely ignore the type since we're not interested in anything except the raw value.
We also ignore all of the other attributes (timestamp, presentation, multi counter values...) We also ignore all of the other attributes (timestamp, presentation, multi counter values...)
@@ -464,12 +461,10 @@ func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, value
*/ */
switch counterDef.CounterSize { switch counterDef.CounterSize {
case 4: case 4:
value = int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)])) return int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)]))
case 8: case 8:
value = int64(bo.Uint64(buffer[valueOffset:(valueOffset + 8)])) return int64(bo.Uint64(buffer[valueOffset:(valueOffset + 8)]))
default: default:
value = int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)])) return int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)]))
} }
return
} }

View File

@@ -1,4 +1,4 @@
package perflib package v1
import ( import (
"testing" "testing"

View File

@@ -1,4 +1,4 @@
package perflib package v1
import ( import (
"encoding/binary" "encoding/binary"

View File

@@ -1,4 +1,4 @@
package perflib package v1
import ( import (
"errors" "errors"
@@ -6,12 +6,8 @@ import (
"log/slog" "log/slog"
"reflect" "reflect"
"strings" "strings"
)
// Conversion factors. "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
const (
TicksToSecondScaleFactor = 1 / 1e7
WindowsEpoch = 116444736000000000
) )
func UnmarshalObject(obj *PerfObject, vs interface{}, logger *slog.Logger) error { func UnmarshalObject(obj *PerfObject, vs interface{}, logger *slog.Logger) error {
@@ -94,10 +90,10 @@ func UnmarshalObject(obj *PerfObject, vs interface{}, logger *slog.Logger) error
} }
switch ctr.Def.CounterType { switch ctr.Def.CounterType {
case PERF_ELAPSED_TIME: case perftypes.PERF_ELAPSED_TIME:
target.Field(i).SetFloat(float64(ctr.Value-WindowsEpoch) / float64(obj.Frequency)) target.Field(i).SetFloat(float64(ctr.Value-perftypes.WindowsEpoch) / float64(obj.Frequency))
case PERF_100NSEC_TIMER, PERF_PRECISION_100NS_TIMER: case perftypes.PERF_100NSEC_TIMER, perftypes.PERF_PRECISION_100NS_TIMER:
target.Field(i).SetFloat(float64(ctr.Value) * TicksToSecondScaleFactor) target.Field(i).SetFloat(float64(ctr.Value) * perftypes.TicksToSecondScaleFactor)
default: default:
target.Field(i).SetFloat(float64(ctr.Value)) target.Field(i).SetFloat(float64(ctr.Value))
} }

View File

@@ -1,4 +1,4 @@
package perflib package v1
import ( import (
"encoding/binary" "encoding/binary"

View File

@@ -1,4 +1,4 @@
package perflib package v1
import ( import (
"strconv" "strconv"

View File

@@ -1,10 +1,12 @@
package perflib package v1
import ( import (
"io" "io"
"log/slog" "log/slog"
"reflect" "reflect"
"testing" "testing"
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
) )
type simple struct { type simple struct {
@@ -38,7 +40,7 @@ func TestUnmarshalPerflib(t *testing.T) {
{ {
Def: &PerfCounterDef{ Def: &PerfCounterDef{
Name: "Something", Name: "Something",
CounterType: PERF_COUNTER_COUNTER, CounterType: perftypes.PERF_COUNTER_COUNTER,
}, },
Value: 123, Value: 123,
}, },
@@ -58,14 +60,14 @@ func TestUnmarshalPerflib(t *testing.T) {
{ {
Def: &PerfCounterDef{ Def: &PerfCounterDef{
Name: "Something", Name: "Something",
CounterType: PERF_COUNTER_COUNTER, CounterType: perftypes.PERF_COUNTER_COUNTER,
}, },
Value: 123, Value: 123,
}, },
{ {
Def: &PerfCounterDef{ Def: &PerfCounterDef{
Name: "Something Else", Name: "Something Else",
CounterType: PERF_COUNTER_COUNTER, CounterType: perftypes.PERF_COUNTER_COUNTER,
HasSecondValue: true, HasSecondValue: true,
}, },
Value: 256, Value: 256,
@@ -87,7 +89,7 @@ func TestUnmarshalPerflib(t *testing.T) {
{ {
Def: &PerfCounterDef{ Def: &PerfCounterDef{
Name: "Something", Name: "Something",
CounterType: PERF_COUNTER_COUNTER, CounterType: perftypes.PERF_COUNTER_COUNTER,
}, },
Value: 321, Value: 321,
}, },
@@ -98,7 +100,7 @@ func TestUnmarshalPerflib(t *testing.T) {
{ {
Def: &PerfCounterDef{ Def: &PerfCounterDef{
Name: "Something", Name: "Something",
CounterType: PERF_COUNTER_COUNTER, CounterType: perftypes.PERF_COUNTER_COUNTER,
}, },
Value: 231, Value: 231,
}, },

View File

@@ -1,22 +1,19 @@
//go:build windows //go:build windows
package perfdata package v2
import ( import (
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
"time"
"unsafe" "unsafe"
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
) )
const EmptyInstance = "------"
type Collector struct { type Collector struct {
time time.Time
object string object string
counters map[string]Counter counters map[string]Counter
handle pdhQueryHandle handle pdhQueryHandle
@@ -30,12 +27,6 @@ type Counter struct {
Frequency float64 Frequency float64
} }
type CounterValues struct {
Type prometheus.ValueType
FirstValue float64
SecondValue float64
}
func NewCollector(object string, instances []string, counters []string) (*Collector, error) { func NewCollector(object string, instances []string, counters []string) (*Collector, error) {
var handle pdhQueryHandle var handle pdhQueryHandle
@@ -44,7 +35,7 @@ func NewCollector(object string, instances []string, counters []string) (*Collec
} }
if len(instances) == 0 { if len(instances) == 0 {
instances = []string{EmptyInstance} instances = []string{perftypes.EmptyInstance}
} }
collector := &Collector{ collector := &Collector{
@@ -127,18 +118,16 @@ func (c *Collector) Describe() map[string]string {
return desc return desc
} }
func (c *Collector) Collect() (map[string]map[string]CounterValues, error) { func (c *Collector) Collect() (map[string]map[string]perftypes.CounterValues, error) {
if len(c.counters) == 0 { if len(c.counters) == 0 {
return map[string]map[string]CounterValues{}, nil return map[string]map[string]perftypes.CounterValues{}, nil
} }
if ret := PdhCollectQueryData(c.handle); ret != ErrorSuccess { if ret := PdhCollectQueryData(c.handle); ret != ErrorSuccess {
return nil, fmt.Errorf("failed to collect query data: %w", NewPdhError(ret)) return nil, fmt.Errorf("failed to collect query data: %w", NewPdhError(ret))
} }
c.time = time.Now() var data map[string]map[string]perftypes.CounterValues
var data map[string]map[string]CounterValues
for _, counter := range c.counters { for _, counter := range c.counters {
for _, instance := range counter.Instances { for _, instance := range counter.Instances {
@@ -167,11 +156,11 @@ func (c *Collector) Collect() (map[string]map[string]CounterValues, error) {
items := (*[1 << 20]PdhRawCounterItem)(unsafe.Pointer(&buf[0]))[:itemCount] items := (*[1 << 20]PdhRawCounterItem)(unsafe.Pointer(&buf[0]))[:itemCount]
if data == nil { if data == nil {
data = make(map[string]map[string]CounterValues, itemCount) data = make(map[string]map[string]perftypes.CounterValues, itemCount)
} }
var metricType prometheus.ValueType var metricType prometheus.ValueType
if val, ok := supportedCounterTypes[counter.Type]; ok { if val, ok := perftypes.SupportedCounterTypes[counter.Type]; ok {
metricType = val metricType = val
} else { } else {
metricType = prometheus.GaugeValue metricType = prometheus.GaugeValue
@@ -184,15 +173,15 @@ func (c *Collector) Collect() (map[string]map[string]CounterValues, error) {
continue continue
} }
if instanceName == "" { if instanceName == "" || instanceName == "*" {
instanceName = EmptyInstance instanceName = perftypes.EmptyInstance
} }
if _, ok := data[instanceName]; !ok { if _, ok := data[instanceName]; !ok {
data[instanceName] = make(map[string]CounterValues, len(c.counters)) data[instanceName] = make(map[string]perftypes.CounterValues, len(c.counters))
} }
values := CounterValues{ values := perftypes.CounterValues{
Type: metricType, Type: metricType,
} }
@@ -201,12 +190,12 @@ func (c *Collector) Collect() (map[string]map[string]CounterValues, error) {
// Ref: https://learn.microsoft.com/en-us/windows/win32/perfctrs/calculating-counter-values // Ref: https://learn.microsoft.com/en-us/windows/win32/perfctrs/calculating-counter-values
switch counter.Type { switch counter.Type {
case PERF_ELAPSED_TIME: case perftypes.PERF_ELAPSED_TIME:
values.FirstValue = float64(item.RawValue.FirstValue-WindowsEpoch) / counter.Frequency values.FirstValue = float64(item.RawValue.FirstValue-perftypes.WindowsEpoch) / counter.Frequency
values.SecondValue = float64(item.RawValue.SecondValue-WindowsEpoch) / counter.Frequency values.SecondValue = float64(item.RawValue.SecondValue-perftypes.WindowsEpoch) / counter.Frequency
case PERF_100NSEC_TIMER, PERF_PRECISION_100NS_TIMER: case perftypes.PERF_100NSEC_TIMER, perftypes.PERF_PRECISION_100NS_TIMER:
values.FirstValue = float64(item.RawValue.FirstValue) * TicksToSecondScaleFactor values.FirstValue = float64(item.RawValue.FirstValue) * perftypes.TicksToSecondScaleFactor
values.SecondValue = float64(item.RawValue.SecondValue) * TicksToSecondScaleFactor values.SecondValue = float64(item.RawValue.SecondValue) * perftypes.TicksToSecondScaleFactor
default: default:
values.FirstValue = float64(item.RawValue.FirstValue) values.FirstValue = float64(item.RawValue.FirstValue)
values.SecondValue = float64(item.RawValue.SecondValue) values.SecondValue = float64(item.RawValue.SecondValue)
@@ -228,7 +217,7 @@ func (c *Collector) Close() {
func formatCounterPath(object, instance, counterName string) string { func formatCounterPath(object, instance, counterName string) string {
var counterPath string var counterPath string
if instance == EmptyInstance { if instance == perftypes.EmptyInstance {
counterPath = fmt.Sprintf(`\%s\%s`, object, counterName) counterPath = fmt.Sprintf(`\%s\%s`, object, counterName)
} else { } else {
counterPath = fmt.Sprintf(`\%s(%s)\%s`, object, instance, counterName) counterPath = fmt.Sprintf(`\%s(%s)\%s`, object, instance, counterName)

View File

@@ -1,9 +1,9 @@
package perfdata_test package v2_test
import ( import (
"testing" "testing"
"github.com/prometheus-community/windows_exporter/internal/perfdata" v2 "github.com/prometheus-community/windows_exporter/internal/perfdata/v2"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -38,7 +38,7 @@ func BenchmarkTestCollector(b *testing.B) {
"Working Set Peak", "Working Set Peak",
"Working Set", "Working Set",
} }
performanceData, err := perfdata.NewCollector("Process", []string{"*"}, counters) performanceData, err := v2.NewCollector("Process", []string{"*"}, counters)
require.NoError(b, err) require.NoError(b, err)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {

View File

@@ -1,12 +1,12 @@
//go:build windows //go:build windows
package perfdata_test package v2_test
import ( import (
"testing" "testing"
"time" "time"
"github.com/prometheus-community/windows_exporter/internal/perfdata" v2 "github.com/prometheus-community/windows_exporter/internal/perfdata/v2"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -61,7 +61,7 @@ func TestCollector(t *testing.T) {
t.Run(tc.object, func(t *testing.T) { t.Run(tc.object, func(t *testing.T) {
t.Parallel() t.Parallel()
performanceData, err := perfdata.NewCollector(tc.object, tc.instances, tc.counters) performanceData, err := v2.NewCollector(tc.object, tc.instances, tc.counters)
require.NoError(t, err) require.NoError(t, err)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)

View File

@@ -1,4 +1,4 @@
package perfdata package v2
import "errors" import "errors"

View File

@@ -31,7 +31,7 @@
//go:build windows //go:build windows
package perfdata package v2
import ( import (
"fmt" "fmt"
@@ -44,10 +44,9 @@ import (
// Error codes. // Error codes.
const ( const (
ErrorSuccess = 0 ErrorSuccess = 0
ErrorFailure = 1 ErrorFailure = 1
ErrorInvalidFunction = 1 ErrorInvalidFunction = 1
EpochDifferenceMicros int64 = 11644473600000000
) )
type ( type (
@@ -289,13 +288,13 @@ var (
// \\LogicalDisk(C:)\% Free Space // \\LogicalDisk(C:)\% Free Space
// //
// To view all (internationalized...) counters on a system, there are three non-programmatic ways: perfmon utility, // To view all (internationalized...) counters on a system, there are three non-programmatic ways: perfmon utility,
// the typeperf command, and the registry editor. perfmon.exe is perhaps the easiest way, because it's basically a // the typeperf command, and the v1 editor. perfmon.exe is perhaps the easiest way, because it's basically a
// full implementation of the pdh.dll API, except with a GUI and all that. The registry setting also provides an // full implementation of the pdh.dll API, except with a GUI and all that. The v1 setting also provides an
// interface to the available counters, and can be found at the following key: // interface to the available counters, and can be found at the following key:
// //
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage
// //
// This registry key contains several values as follows: // This v1 key contains several values as follows:
// //
// 1 // 1
// 1847 // 1847
@@ -325,12 +324,6 @@ func PdhAddCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData u
return uint32(ret) return uint32(ret)
} }
// PdhAddEnglishCounterSupported returns true if PdhAddEnglishCounterW Win API function was found in pdh.dll.
// PdhAddEnglishCounterW function is not supported on pre-Windows Vista systems.
func PdhAddEnglishCounterSupported() bool {
return pdhAddEnglishCounterW != nil
}
// PdhAddEnglishCounter adds the specified language-neutral counter to the query. See the PdhAddCounter function. This function only exists on // PdhAddEnglishCounter adds the specified language-neutral counter to the query. See the PdhAddCounter function. This function only exists on
// Windows versions higher than Vista. // Windows versions higher than Vista.
func PdhAddEnglishCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData uintptr, phCounter *pdhCounterHandle) uint32 { func PdhAddEnglishCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData uintptr, phCounter *pdhCounterHandle) uint32 {

View File

@@ -31,7 +31,7 @@
//go:build windows //go:build windows
package perfdata package v2
import "golang.org/x/sys/windows" import "golang.org/x/sys/windows"

View File

@@ -31,7 +31,7 @@
//go:build windows //go:build windows
package perfdata package v2
import "golang.org/x/sys/windows" import "golang.org/x/sys/windows"

View File

@@ -1,10 +0,0 @@
package perflib
// Based on https://github.com/leoluk/perflib_exporter/blob/master/collector/mapper.go
const (
PERF_COUNTER_COUNTER = 0x10410400
PERF_100NSEC_TIMER = 0x20510500
PERF_PRECISION_100NS_TIMER = 0x20570500
PERF_ELAPSED_TIME = 0x30240500
)

View File

@@ -1,9 +1,9 @@
package types package types
import ( import (
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
) )
type ScrapeContext struct { type ScrapeContext struct {
PerfObjects map[string]*perflib.PerfObject PerfObjects map[string]*v1.PerfObject
} }

View File

@@ -8,6 +8,7 @@ import (
"log/slog" "log/slog"
"slices" "slices"
"strings" "strings"
"sync"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/collector/ad" "github.com/prometheus-community/windows_exporter/internal/collector/ad"
@@ -58,7 +59,7 @@ import (
"github.com/prometheus-community/windows_exporter/internal/collector/updates" "github.com/prometheus-community/windows_exporter/internal/collector/updates"
"github.com/prometheus-community/windows_exporter/internal/collector/vmware" "github.com/prometheus-community/windows_exporter/internal/collector/vmware"
"github.com/prometheus-community/windows_exporter/internal/collector/vmware_blast" "github.com/prometheus-community/windows_exporter/internal/collector/vmware_blast"
"github.com/prometheus-community/windows_exporter/internal/perflib" v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
"github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus-community/windows_exporter/internal/types"
"github.com/yusufpapurcu/wmi" "github.com/yusufpapurcu/wmi"
) )
@@ -159,7 +160,7 @@ func (c *MetricCollectors) SetPerfCounterQuery(logger *slog.Logger) error {
perfIndicies = make([]string, 0, len(perfCounterNames)) perfIndicies = make([]string, 0, len(perfCounterNames))
for _, cn := range perfCounterNames { for _, cn := range perfCounterNames {
perfIndicies = append(perfIndicies, perflib.MapCounterToIndex(cn)) perfIndicies = append(perfIndicies, v1.MapCounterToIndex(cn))
} }
perfCounterDependencies = append(perfCounterDependencies, strings.Join(perfIndicies, " ")) perfCounterDependencies = append(perfCounterDependencies, strings.Join(perfIndicies, " "))
@@ -188,13 +189,31 @@ func (c *MetricCollectors) Build(logger *slog.Logger) error {
return fmt.Errorf("initialize SWbemServices: %w", err) return fmt.Errorf("initialize SWbemServices: %w", err)
} }
wg := sync.WaitGroup{}
wg.Add(len(c.Collectors))
errCh := make(chan error, len(c.Collectors))
errs := make([]error, 0, len(c.Collectors))
for _, collector := range c.Collectors { for _, collector := range c.Collectors {
if err = collector.Build(logger, c.WMIClient); err != nil { go func() {
return fmt.Errorf("error build collector %s: %w", collector.GetName(), err) defer wg.Done()
}
if err = collector.Build(logger, c.WMIClient); err != nil {
errCh <- fmt.Errorf("error build collector %s: %w", collector.GetName(), err)
}
}()
} }
return nil wg.Wait()
close(errCh)
for err := range errCh {
errs = append(errs, err)
}
return errors.Join(errs...)
} }
// PrepareScrapeContext creates a ScrapeContext to be used during a single scrape. // PrepareScrapeContext creates a ScrapeContext to be used during a single scrape.
@@ -204,7 +223,7 @@ func (c *MetricCollectors) PrepareScrapeContext() (*types.ScrapeContext, error)
return &types.ScrapeContext{}, nil return &types.ScrapeContext{}, nil
} }
perfObjects, err := perflib.GetPerflibSnapshot(c.PerfCounterQuery) perfObjects, err := v1.GetPerflibSnapshot(c.PerfCounterQuery)
if err != nil { if err != nil {
return nil, err return nil, err
} }