diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 87055671..2ecc7756 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: 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 tar.exe xvf buildkit.tar.gz - + .\bin\buildkitd.exe --register-service Start-Service buildkitd - name: Setup Docker Buildx @@ -75,32 +75,32 @@ jobs: - name: Build run: | $ErrorActionPreference = "Stop" - + $Version = git describe --tags --always $Version = $Version -replace 'v', '' # '+' symbols are invalid characters in image tags $Version = $Version -replace '\+', '_' $Version | Set-Content VERSION -PassThru - + make build-all - + # GH requires all files to have different names, so add version/arch to differentiate foreach($Arch in "amd64", "arm64") { Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe } - + Get-ChildItem -Path output - name: Build Release Artifacts run: | $ErrorActionPreference = "Stop" $Version = Get-Content VERSION - + foreach($Arch in "amd64", "arm64") { Write-Host "Building windows_exporter $Version msi for $Arch" .\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch" } - + Move-Item installer\*.msi output\ Get-ChildItem -Path output\ @@ -119,7 +119,7 @@ jobs: env: 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 ) diff --git a/.golangci.yaml b/.golangci.yaml index 4179483f..8b54eba8 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -83,7 +83,7 @@ issues: - text: "don't use ALL_CAPS in Go names; use CamelCase" linters: - revive - - path: internal/perflib/ + - path: internal/perfdata/v1/ linters: - godox - stylecheck diff --git a/internal/collector/ad/ad.go b/internal/collector/ad/ad.go index c90ca6df..09b72058 100644 --- a/internal/collector/ad/ad.go +++ b/internal/collector/ad/ad.go @@ -10,7 +10,6 @@ import ( "github.com/alecthomas/kingpin/v2" "github.com/prometheus-community/windows_exporter/internal/perfdata" "github.com/prometheus-community/windows_exporter/internal/types" - "github.com/prometheus-community/windows_exporter/internal/utils" "github.com/prometheus/client_golang/prometheus" "github.com/yusufpapurcu/wmi" ) @@ -23,10 +22,9 @@ var ConfigDefaults = Config{} // A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DirectoryServices_DirectoryServices metrics. type Collector struct { - config Config - wmiClient *wmi.Client + config Config - perfDataCollector *perfdata.Collector + perfDataCollector perfdata.Collector addressBookClientSessions *prometheus.Desc addressBookOperationsTotal *prometheus.Desc @@ -120,169 +118,161 @@ func (c *Collector) Close(_ *slog.Logger) error { return nil } -func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error { - if wmiClient == nil || wmiClient.SWbemServicesClient == nil { - return errors.New("wmiClient or SWbemServicesClient is nil") +func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error { + counters := []string{ + abANRPerSec, + abBrowsesPerSec, + abClientSessions, + abMatchesPerSec, + abPropertyReadsPerSec, + abProxyLookupsPerSec, + abSearchesPerSec, + approximateHighestDNT, + atqEstimatedQueueDelay, + atqOutstandingQueuedRequests, + atqRequestLatency, + atqThreadsLDAP, + atqThreadsOther, + atqThreadsTotal, + baseSearchesPerSec, + databaseAddsPerSec, + databaseDeletesPerSec, + databaseModifiesPerSec, + databaseRecyclesPerSec, + digestBindsPerSec, + draHighestUSNCommittedHighPart, + draHighestUSNCommittedLowPart, + draHighestUSNIssuedHighPart, + draHighestUSNIssuedLowPart, + draInboundBytesCompressedBetweenSitesAfterCompressionSinceBoot, + draInboundBytesCompressedBetweenSitesAfterCompressionPerSec, + draInboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot, + draInboundBytesCompressedBetweenSitesBeforeCompressionPerSec, + draInboundBytesNotCompressedWithinSiteSinceBoot, + draInboundBytesNotCompressedWithinSitePerSec, + draInboundBytesTotalSinceBoot, + draInboundBytesTotalPerSec, + draInboundFullSyncObjectsRemaining, + draInboundLinkValueUpdatesRemainingInPacket, + draInboundObjectUpdatesRemainingInPacket, + draInboundObjectsAppliedPerSec, + draInboundObjectsFilteredPerSec, + draInboundObjectsPerSec, + draInboundPropertiesAppliedPerSec, + draInboundPropertiesFilteredPerSec, + draInboundPropertiesTotalPerSec, + draInboundTotalUpdatesRemainingInPacket, + draInboundValuesDNsOnlyPerSec, + draInboundValuesTotalPerSec, + draOutboundBytesCompressedBetweenSitesAfterCompressionSinceBoot, + draOutboundBytesCompressedBetweenSitesAfterCompressionPerSec, + draOutboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot, + draOutboundBytesCompressedBetweenSitesBeforeCompressionPerSec, + draOutboundBytesNotCompressedWithinSiteSinceBoot, + draOutboundBytesNotCompressedWithinSitePerSec, + draOutboundBytesTotalSinceBoot, + draOutboundBytesTotalPerSec, + draOutboundObjectsFilteredPerSec, + draOutboundObjectsPerSec, + draOutboundPropertiesPerSec, + draOutboundValuesDNsOnlyPerSec, + draOutboundValuesTotalPerSec, + draPendingReplicationOperations, + draPendingReplicationSynchronizations, + draSyncFailuresOnSchemaMismatch, + draSyncRequestsMade, + draSyncRequestsSuccessful, + draThreadsGettingNCChanges, + draThreadsGettingNCChangesHoldingSemaphore, + dsPercentReadsFromDRA, + dsPercentReadsFromKCC, + dsPercentReadsFromLSA, + dsPercentReadsFromNSPI, + dsPercentReadsFromNTDSAPI, + dsPercentReadsFromSAM, + dsPercentReadsOther, + dsPercentSearchesFromDRA, + dsPercentSearchesFromKCC, + dsPercentSearchesFromLDAP, + dsPercentSearchesFromLSA, + dsPercentSearchesFromNSPI, + dsPercentSearchesFromNTDSAPI, + dsPercentSearchesFromSAM, + dsPercentSearchesOther, + dsPercentWritesFromDRA, + dsPercentWritesFromKCC, + dsPercentWritesFromLDAP, + dsPercentWritesFromLSA, + dsPercentWritesFromNSPI, + dsPercentWritesFromNTDSAPI, + dsPercentWritesFromSAM, + dsPercentWritesOther, + dsClientBindsPerSec, + dsClientNameTranslationsPerSec, + dsDirectoryReadsPerSec, + dsDirectorySearchesPerSec, + dsDirectoryWritesPerSec, + dsMonitorListSize, + dsNameCacheHitRate, + dsNotifyQueueSize, + dsSearchSubOperationsPerSec, + dsSecurityDescriptorPropagationsEvents, + dsSecurityDescriptorPropagatorAverageExclusionTime, + dsSecurityDescriptorPropagatorRuntimeQueue, + dsSecurityDescriptorSubOperationsPerSec, + dsServerBindsPerSec, + dsServerNameTranslationsPerSec, + dsThreadsInUse, + externalBindsPerSec, + fastBindsPerSec, + ldapActiveThreads, + ldapBindTime, + ldapClientSessions, + ldapClosedConnectionsPerSec, + ldapNewConnectionsPerSec, + ldapNewSSLConnectionsPerSec, + ldapSearchesPerSec, + ldapSuccessfulBindsPerSec, + ldapUDPOperationsPerSec, + ldapWritesPerSec, + linkValuesCleanedPerSec, + negotiatedBindsPerSec, + ntlmBindsPerSec, + oneLevelSearchesPerSec, + phantomsCleanedPerSec, + phantomsVisitedPerSec, + samAccountGroupEvaluationLatency, + samDisplayInformationQueriesPerSec, + samDomainLocalGroupMembershipEvaluationsPerSec, + samEnumerationsPerSec, + samGCEvaluationsPerSec, + samGlobalGroupMembershipEvaluationsPerSec, + samMachineCreationAttemptsPerSec, + samMembershipChangesPerSec, + samNonTransitiveMembershipEvaluationsPerSec, + samPasswordChangesPerSec, + samResourceGroupEvaluationLatency, + samSuccessfulComputerCreationsPerSecIncludesAllRequests, + samSuccessfulUserCreationsPerSec, + samTransitiveMembershipEvaluationsPerSec, + samUniversalGroupMembershipEvaluationsPerSec, + samUserCreationAttemptsPerSec, + simpleBindsPerSec, + subtreeSearchesPerSec, + tombstonesGarbageCollectedPerSec, + tombstonesVisitedPerSec, + transitiveOperationsMillisecondsRun, + transitiveOperationsPerSec, + transitiveSubOperationsPerSec, } - if utils.PDHEnabled() { - counters := []string{ - abANRPerSec, - abBrowsesPerSec, - abClientSessions, - abMatchesPerSec, - abPropertyReadsPerSec, - abProxyLookupsPerSec, - abSearchesPerSec, - approximateHighestDNT, - atqEstimatedQueueDelay, - atqOutstandingQueuedRequests, - atqRequestLatency, - atqThreadsLDAP, - atqThreadsOther, - atqThreadsTotal, - baseSearchesPerSec, - databaseAddsPerSec, - databaseDeletesPerSec, - databaseModifiesPerSec, - databaseRecyclesPerSec, - digestBindsPerSec, - draHighestUSNCommittedHighPart, - draHighestUSNCommittedLowPart, - draHighestUSNIssuedHighPart, - draHighestUSNIssuedLowPart, - draInboundBytesCompressedBetweenSitesAfterCompressionSinceBoot, - draInboundBytesCompressedBetweenSitesAfterCompressionPerSec, - draInboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot, - draInboundBytesCompressedBetweenSitesBeforeCompressionPerSec, - draInboundBytesNotCompressedWithinSiteSinceBoot, - draInboundBytesNotCompressedWithinSitePerSec, - draInboundBytesTotalSinceBoot, - draInboundBytesTotalPerSec, - draInboundFullSyncObjectsRemaining, - draInboundLinkValueUpdatesRemainingInPacket, - draInboundObjectUpdatesRemainingInPacket, - draInboundObjectsAppliedPerSec, - draInboundObjectsFilteredPerSec, - draInboundObjectsPerSec, - draInboundPropertiesAppliedPerSec, - draInboundPropertiesFilteredPerSec, - draInboundPropertiesTotalPerSec, - draInboundTotalUpdatesRemainingInPacket, - draInboundValuesDNsOnlyPerSec, - draInboundValuesTotalPerSec, - draOutboundBytesCompressedBetweenSitesAfterCompressionSinceBoot, - draOutboundBytesCompressedBetweenSitesAfterCompressionPerSec, - draOutboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot, - draOutboundBytesCompressedBetweenSitesBeforeCompressionPerSec, - draOutboundBytesNotCompressedWithinSiteSinceBoot, - draOutboundBytesNotCompressedWithinSitePerSec, - draOutboundBytesTotalSinceBoot, - draOutboundBytesTotalPerSec, - draOutboundObjectsFilteredPerSec, - draOutboundObjectsPerSec, - draOutboundPropertiesPerSec, - draOutboundValuesDNsOnlyPerSec, - draOutboundValuesTotalPerSec, - draPendingReplicationOperations, - draPendingReplicationSynchronizations, - draSyncFailuresOnSchemaMismatch, - draSyncRequestsMade, - draSyncRequestsSuccessful, - draThreadsGettingNCChanges, - draThreadsGettingNCChangesHoldingSemaphore, - dsPercentReadsFromDRA, - dsPercentReadsFromKCC, - dsPercentReadsFromLSA, - dsPercentReadsFromNSPI, - dsPercentReadsFromNTDSAPI, - dsPercentReadsFromSAM, - dsPercentReadsOther, - dsPercentSearchesFromDRA, - dsPercentSearchesFromKCC, - dsPercentSearchesFromLDAP, - dsPercentSearchesFromLSA, - dsPercentSearchesFromNSPI, - dsPercentSearchesFromNTDSAPI, - dsPercentSearchesFromSAM, - dsPercentSearchesOther, - dsPercentWritesFromDRA, - dsPercentWritesFromKCC, - dsPercentWritesFromLDAP, - dsPercentWritesFromLSA, - dsPercentWritesFromNSPI, - dsPercentWritesFromNTDSAPI, - dsPercentWritesFromSAM, - dsPercentWritesOther, - dsClientBindsPerSec, - dsClientNameTranslationsPerSec, - dsDirectoryReadsPerSec, - dsDirectorySearchesPerSec, - dsDirectoryWritesPerSec, - dsMonitorListSize, - dsNameCacheHitRate, - dsNotifyQueueSize, - dsSearchSubOperationsPerSec, - dsSecurityDescriptorPropagationsEvents, - dsSecurityDescriptorPropagatorAverageExclusionTime, - dsSecurityDescriptorPropagatorRuntimeQueue, - dsSecurityDescriptorSubOperationsPerSec, - dsServerBindsPerSec, - dsServerNameTranslationsPerSec, - dsThreadsInUse, - externalBindsPerSec, - fastBindsPerSec, - ldapActiveThreads, - ldapBindTime, - ldapClientSessions, - ldapClosedConnectionsPerSec, - ldapNewConnectionsPerSec, - ldapNewSSLConnectionsPerSec, - ldapSearchesPerSec, - ldapSuccessfulBindsPerSec, - ldapUDPOperationsPerSec, - ldapWritesPerSec, - linkValuesCleanedPerSec, - negotiatedBindsPerSec, - ntlmBindsPerSec, - oneLevelSearchesPerSec, - phantomsCleanedPerSec, - phantomsVisitedPerSec, - samAccountGroupEvaluationLatency, - samDisplayInformationQueriesPerSec, - samDomainLocalGroupMembershipEvaluationsPerSec, - samEnumerationsPerSec, - samGCEvaluationsPerSec, - samGlobalGroupMembershipEvaluationsPerSec, - samMachineCreationAttemptsPerSec, - samMembershipChangesPerSec, - samNonTransitiveMembershipEvaluationsPerSec, - samPasswordChangesPerSec, - samResourceGroupEvaluationLatency, - samSuccessfulComputerCreationsPerSecIncludesAllRequests, - samSuccessfulUserCreationsPerSec, - samTransitiveMembershipEvaluationsPerSec, - samUniversalGroupMembershipEvaluationsPerSec, - samUserCreationAttemptsPerSec, - simpleBindsPerSec, - subtreeSearchesPerSec, - tombstonesGarbageCollectedPerSec, - tombstonesVisitedPerSec, - transitiveOperationsMillisecondsRun, - transitiveOperationsPerSec, - transitiveSubOperationsPerSec, - } + var err error - var err error - - c.perfDataCollector, err = perfdata.NewCollector("DirectoryServices", []string{"*"}, counters) - if err != nil { - return fmt.Errorf("failed to create DirectoryServices collector: %w", err) - } + c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "DirectoryServices", perfdata.AllInstances, counters) + if err != nil { + return fmt.Errorf("failed to create DirectoryServices collector: %w", err) } - c.wmiClient = wmiClient - c.addressBookOperationsTotal = prometheus.NewDesc( prometheus.BuildFQName(types.Namespace, Name, "address_book_operations_total"), "", @@ -662,734 +652,17 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error { // Collect sends the metric values for each metric // to the provided prometheus Metric channel. -func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error { - if utils.PDHEnabled() { - return c.collectPDH(ch) - } - - logger = logger.With(slog.String("collector", Name)) - if err := c.collect(ch); err != nil { - logger.Error("failed collecting ad metrics", - slog.Any("err", err), - ) - - return err - } - - return nil +func (c *Collector) Collect(_ *types.ScrapeContext, _ *slog.Logger, ch chan<- prometheus.Metric) error { + return c.collect(ch) } func (c *Collector) collect(ch chan<- prometheus.Metric) error { - var dst []Win32_PerfRawData_DirectoryServices_DirectoryServices - if err := c.wmiClient.Query("SELECT * FROM Win32_PerfRawData_DirectoryServices_DirectoryServices", &dst); err != nil { - return err - } - - if len(dst) == 0 { - return errors.New("WMI query returned empty result set") - } - - ch <- prometheus.MustNewConstMetric( - c.addressBookOperationsTotal, - prometheus.CounterValue, - float64(dst[0].ABANRPersec), - "ambiguous_name_resolution", - ) - ch <- prometheus.MustNewConstMetric( - c.addressBookOperationsTotal, - prometheus.CounterValue, - float64(dst[0].ABBrowsesPersec), - "browse", - ) - ch <- prometheus.MustNewConstMetric( - c.addressBookOperationsTotal, - prometheus.CounterValue, - float64(dst[0].ABMatchesPersec), - "find", - ) - ch <- prometheus.MustNewConstMetric( - c.addressBookOperationsTotal, - prometheus.CounterValue, - float64(dst[0].ABPropertyReadsPersec), - "property_read", - ) - ch <- prometheus.MustNewConstMetric( - c.addressBookOperationsTotal, - prometheus.CounterValue, - float64(dst[0].ABSearchesPersec), - "search", - ) - ch <- prometheus.MustNewConstMetric( - c.addressBookOperationsTotal, - prometheus.CounterValue, - float64(dst[0].ABProxyLookupsPersec), - "proxy_search", - ) - - ch <- prometheus.MustNewConstMetric( - c.addressBookClientSessions, - prometheus.GaugeValue, - float64(dst[0].ABClientSessions), - ) - - ch <- prometheus.MustNewConstMetric( - c.approximateHighestDistinguishedNameTag, - prometheus.GaugeValue, - float64(dst[0].ApproximatehighestDNT), - ) - - ch <- prometheus.MustNewConstMetric( - c.atqEstimatedDelaySeconds, - prometheus.GaugeValue, - float64(dst[0].ATQEstimatedQueueDelay)/1000, - ) - ch <- prometheus.MustNewConstMetric( - c.atqOutstandingRequests, - prometheus.GaugeValue, - float64(dst[0].ATQOutstandingQueuedRequests), - ) - ch <- prometheus.MustNewConstMetric( - c.atqAverageRequestLatency, - prometheus.GaugeValue, - float64(dst[0].ATQRequestLatency), - ) - ch <- prometheus.MustNewConstMetric( - c.atqCurrentThreads, - prometheus.GaugeValue, - float64(dst[0].ATQThreadsLDAP), - "ldap", - ) - ch <- prometheus.MustNewConstMetric( - c.atqCurrentThreads, - prometheus.GaugeValue, - float64(dst[0].ATQThreadsOther), - "other", - ) - - ch <- prometheus.MustNewConstMetric( - c.searchesTotal, - prometheus.CounterValue, - float64(dst[0].BasesearchesPersec), - "base", - ) - ch <- prometheus.MustNewConstMetric( - c.searchesTotal, - prometheus.CounterValue, - float64(dst[0].SubtreesearchesPersec), - "subtree", - ) - ch <- prometheus.MustNewConstMetric( - c.searchesTotal, - prometheus.CounterValue, - float64(dst[0].OnelevelsearchesPersec), - "one_level", - ) - - ch <- prometheus.MustNewConstMetric( - c.databaseOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DatabaseaddsPersec), - "add", - ) - ch <- prometheus.MustNewConstMetric( - c.databaseOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DatabasedeletesPersec), - "delete", - ) - ch <- prometheus.MustNewConstMetric( - c.databaseOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DatabasemodifysPersec), - "modify", - ) - ch <- prometheus.MustNewConstMetric( - c.databaseOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DatabaserecyclesPersec), - "recycle", - ) - - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].DigestBindsPersec), - "digest", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].DSClientBindsPersec), - "ds_client", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].DSServerBindsPersec), - "ds_server", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].ExternalBindsPersec), - "external", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].FastBindsPersec), - "fast", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].NegotiatedBindsPersec), - "negotiate", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].NTLMBindsPersec), - "ntlm", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].SimpleBindsPersec), - "simple", - ) - ch <- prometheus.MustNewConstMetric( - c.bindsTotal, - prometheus.CounterValue, - float64(dst[0].LDAPSuccessfulBindsPersec), - "ldap", - ) - - ch <- prometheus.MustNewConstMetric( - c.replicationHighestUsn, - prometheus.CounterValue, - float64(dst[0].DRAHighestUSNCommittedHighpart<<32)+float64(dst[0].DRAHighestUSNCommittedLowpart), - "committed", - ) - ch <- prometheus.MustNewConstMetric( - c.replicationHighestUsn, - prometheus.CounterValue, - float64(dst[0].DRAHighestUSNIssuedHighpart<<32)+float64(dst[0].DRAHighestUSNIssuedLowpart), - "issued", - ) - - ch <- prometheus.MustNewConstMetric( - c.interSiteReplicationDataBytesTotal, - prometheus.CounterValue, - float64(dst[0].DRAInboundBytesCompressedBetweenSitesAfterCompressionPersec), - "inbound", - ) - // The pre-compression data size seems to have little value? Skipping for now - // ch <- prometheus.MustNewConstMetric( - // c.interSiteReplicationDataBytesTotal, - // prometheus.CounterValue, - // float64(dst[0].DRAInboundBytesCompressedBetweenSitesBeforeCompressionPersec), - // "inbound", - // ) - ch <- prometheus.MustNewConstMetric( - c.interSiteReplicationDataBytesTotal, - prometheus.CounterValue, - float64(dst[0].DRAOutboundBytesCompressedBetweenSitesAfterCompressionPersec), - "outbound", - ) - // ch <- prometheus.MustNewConstMetric( - // c.interSiteReplicationDataBytesTotal, - // prometheus.CounterValue, - // float64(dst[0].DRAOutboundBytesCompressedBetweenSitesBeforeCompressionPersec), - // "outbound", - // ) - ch <- prometheus.MustNewConstMetric( - c.intraSiteReplicationDataBytesTotal, - prometheus.CounterValue, - float64(dst[0].DRAInboundBytesNotCompressedWithinSitePersec), - "inbound", - ) - ch <- prometheus.MustNewConstMetric( - c.intraSiteReplicationDataBytesTotal, - prometheus.CounterValue, - float64(dst[0].DRAOutboundBytesNotCompressedWithinSitePersec), - "outbound", - ) - - ch <- prometheus.MustNewConstMetric( - c.replicationInboundSyncObjectsRemaining, - prometheus.GaugeValue, - float64(dst[0].DRAInboundFullSyncObjectsRemaining), - ) - - ch <- prometheus.MustNewConstMetric( - c.replicationInboundLinkValueUpdatesRemaining, - prometheus.GaugeValue, - float64(dst[0].DRAInboundLinkValueUpdatesRemaininginPacket), - ) - - ch <- prometheus.MustNewConstMetric( - c.replicationInboundObjectsUpdatedTotal, - prometheus.CounterValue, - float64(dst[0].DRAInboundObjectsAppliedPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.replicationInboundObjectsFilteredTotal, - prometheus.CounterValue, - float64(dst[0].DRAInboundObjectsFilteredPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.replicationInboundPropertiesUpdatedTotal, - prometheus.CounterValue, - float64(dst[0].DRAInboundPropertiesAppliedPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.replicationInboundPropertiesFilteredTotal, - prometheus.CounterValue, - float64(dst[0].DRAInboundPropertiesFilteredPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.replicationPendingOperations, - prometheus.GaugeValue, - float64(dst[0].DRAPendingReplicationOperations), - ) - ch <- prometheus.MustNewConstMetric( - c.replicationPendingSynchronizations, - prometheus.GaugeValue, - float64(dst[0].DRAPendingReplicationSynchronizations), - ) - - ch <- prometheus.MustNewConstMetric( - c.replicationSyncRequestsTotal, - prometheus.CounterValue, - float64(dst[0].DRASyncRequestsMade), - ) - ch <- prometheus.MustNewConstMetric( - c.replicationSyncRequestsSuccessTotal, - prometheus.CounterValue, - float64(dst[0].DRASyncRequestsSuccessful), - ) - ch <- prometheus.MustNewConstMetric( - c.replicationSyncRequestsSchemaMismatchFailureTotal, - prometheus.CounterValue, - float64(dst[0].DRASyncFailuresonSchemaMismatch), - ) - - ch <- prometheus.MustNewConstMetric( - c.nameTranslationsTotal, - prometheus.CounterValue, - float64(dst[0].DSClientNameTranslationsPersec), - "client", - ) - ch <- prometheus.MustNewConstMetric( - c.nameTranslationsTotal, - prometheus.CounterValue, - float64(dst[0].DSServerNameTranslationsPersec), - "server", - ) - - ch <- prometheus.MustNewConstMetric( - c.changeMonitorsRegistered, - prometheus.GaugeValue, - float64(dst[0].DSMonitorListSize), - ) - ch <- prometheus.MustNewConstMetric( - c.changeMonitorUpdatesPending, - prometheus.GaugeValue, - float64(dst[0].DSNotifyQueueSize), - ) - - ch <- prometheus.MustNewConstMetric( - c.nameCacheHitsTotal, - prometheus.CounterValue, - float64(dst[0].DSNameCachehitrate), - ) - ch <- prometheus.MustNewConstMetric( - c.nameCacheLookupsTotal, - prometheus.CounterValue, - float64(dst[0].DSNameCachehitrate_Base), - ) - - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentReadsfromDRA), - "read", - "replication_agent", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentReadsfromKCC), - "read", - "knowledge_consistency_checker", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentReadsfromLSA), - "read", - "local_security_authority", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentReadsfromNSPI), - "read", - "name_service_provider_interface", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentReadsfromNTDSAPI), - "read", - "directory_service_api", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentReadsfromSAM), - "read", - "security_account_manager", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentReadsOther), - "read", - "other", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesfromDRA), - "search", - "replication_agent", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesfromKCC), - "search", - "knowledge_consistency_checker", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesfromLDAP), - "search", - "ldap", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesfromLSA), - "search", - "local_security_authority", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesfromNSPI), - "search", - "name_service_provider_interface", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesfromNTDSAPI), - "search", - "directory_service_api", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesfromSAM), - "search", - "security_account_manager", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentSearchesOther), - "search", - "other", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesfromDRA), - "write", - "replication_agent", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesfromKCC), - "write", - "knowledge_consistency_checker", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesfromLDAP), - "write", - "ldap", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesfromLSA), - "write", - "local_security_authority", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesfromNSPI), - "write", - "name_service_provider_interface", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesfromNTDSAPI), - "write", - "directory_service_api", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesfromSAM), - "write", - "security_account_manager", - ) - ch <- prometheus.MustNewConstMetric( - c.directoryOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSPercentWritesOther), - "write", - "other", - ) - - ch <- prometheus.MustNewConstMetric( - c.directorySearchSubOperationsTotal, - prometheus.CounterValue, - float64(dst[0].DSSearchsuboperationsPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.securityDescriptorPropagationEventsTotal, - prometheus.CounterValue, - float64(dst[0].DSSecurityDescriptorsuboperationsPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.securityDescriptorPropagationEventsQueued, - prometheus.GaugeValue, - float64(dst[0].DSSecurityDescriptorPropagationsEvents), - ) - ch <- prometheus.MustNewConstMetric( - c.securityDescriptorPropagationAccessWaitTotalSeconds, - prometheus.GaugeValue, - float64(dst[0].DSSecurityDescriptorPropagatorAverageExclusionTime), - ) - ch <- prometheus.MustNewConstMetric( - c.securityDescriptorPropagationItemsQueuedTotal, - prometheus.CounterValue, - float64(dst[0].DSSecurityDescriptorPropagatorRuntimeQueue), - ) - - ch <- prometheus.MustNewConstMetric( - c.directoryServiceThreads, - prometheus.GaugeValue, - float64(dst[0].DSThreadsinUse), - ) - - ch <- prometheus.MustNewConstMetric( - c.ldapClosedConnectionsTotal, - prometheus.CounterValue, - float64(dst[0].LDAPClosedConnectionsPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.ldapOpenedConnectionsTotal, - prometheus.CounterValue, - float64(dst[0].LDAPNewConnectionsPersec), - "ldap", - ) - ch <- prometheus.MustNewConstMetric( - c.ldapOpenedConnectionsTotal, - prometheus.CounterValue, - float64(dst[0].LDAPNewSSLConnectionsPersec), - "ldaps", - ) - - ch <- prometheus.MustNewConstMetric( - c.ldapActiveThreads, - prometheus.GaugeValue, - float64(dst[0].LDAPActiveThreads), - ) - - ch <- prometheus.MustNewConstMetric( - c.ldapLastBindTimeSeconds, - prometheus.GaugeValue, - float64(dst[0].LDAPBindTime)/1000, - ) - - ch <- prometheus.MustNewConstMetric( - c.ldapSearchesTotal, - prometheus.CounterValue, - float64(dst[0].LDAPSearchesPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.ldapUdpOperationsTotal, - prometheus.CounterValue, - float64(dst[0].LDAPUDPoperationsPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.ldapWritesTotal, - prometheus.CounterValue, - float64(dst[0].LDAPWritesPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.ldapClientSessions, - prometheus.GaugeValue, - float64(dst[0].LDAPClientSessions), - ) - - ch <- prometheus.MustNewConstMetric( - c.linkValuesCleanedTotal, - prometheus.CounterValue, - float64(dst[0].LinkValuesCleanedPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.phantomObjectsCleanedTotal, - prometheus.CounterValue, - float64(dst[0].PhantomsCleanedPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.phantomObjectsVisitedTotal, - prometheus.CounterValue, - float64(dst[0].PhantomsVisitedPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.samGroupMembershipEvaluationsTotal, - prometheus.CounterValue, - float64(dst[0].SAMGlobalGroupMembershipEvaluationsPersec), - "global", - ) - ch <- prometheus.MustNewConstMetric( - c.samGroupMembershipEvaluationsTotal, - prometheus.CounterValue, - float64(dst[0].SAMDomainLocalGroupMembershipEvaluationsPersec), - "domain_local", - ) - ch <- prometheus.MustNewConstMetric( - c.samGroupMembershipEvaluationsTotal, - prometheus.CounterValue, - float64(dst[0].SAMUniversalGroupMembershipEvaluationsPersec), - "universal", - ) - ch <- prometheus.MustNewConstMetric( - c.samGroupMembershipGlobalCatalogEvaluationsTotal, - prometheus.CounterValue, - float64(dst[0].SAMGCEvaluationsPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.samGroupMembershipEvaluationsNonTransitiveTotal, - prometheus.CounterValue, - float64(dst[0].SAMNonTransitiveMembershipEvaluationsPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.samGroupMembershipEvaluationsTransitiveTotal, - prometheus.CounterValue, - float64(dst[0].SAMTransitiveMembershipEvaluationsPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.samGroupEvaluationLatency, - prometheus.GaugeValue, - float64(dst[0].SAMAccountGroupEvaluationLatency), - "account_group", - ) - ch <- prometheus.MustNewConstMetric( - c.samGroupEvaluationLatency, - prometheus.GaugeValue, - float64(dst[0].SAMResourceGroupEvaluationLatency), - "resource_group", - ) - - ch <- prometheus.MustNewConstMetric( - c.samComputerCreationRequestsTotal, - prometheus.CounterValue, - float64(dst[0].SAMSuccessfulComputerCreationsPersecIncludesallrequests), - ) - ch <- prometheus.MustNewConstMetric( - c.samComputerCreationSuccessfulRequestsTotal, - prometheus.CounterValue, - float64(dst[0].SAMMachineCreationAttemptsPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.samUserCreationRequestsTotal, - prometheus.CounterValue, - float64(dst[0].SAMUserCreationAttemptsPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.samUserCreationSuccessfulRequestsTotal, - prometheus.CounterValue, - float64(dst[0].SAMSuccessfulUserCreationsPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.samQueryDisplayRequestsTotal, - prometheus.CounterValue, - float64(dst[0].SAMDisplayInformationQueriesPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.samEnumerationsTotal, - prometheus.CounterValue, - float64(dst[0].SAMEnumerationsPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.samMembershipChangesTotal, - prometheus.CounterValue, - float64(dst[0].SAMMembershipChangesPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.samPasswordChangesTotal, - prometheus.CounterValue, - float64(dst[0].SAMPasswordChangesPersec), - ) - - ch <- prometheus.MustNewConstMetric( - c.tombstonesObjectsCollectedTotal, - prometheus.CounterValue, - float64(dst[0].TombstonesGarbageCollectedPersec), - ) - ch <- prometheus.MustNewConstMetric( - c.tombstonesObjectsVisitedTotal, - prometheus.CounterValue, - float64(dst[0].TombstonesVisitedPersec), - ) - - return nil -} - -func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { - data, err := c.perfDataCollector.Collect() + perfData, err := c.perfDataCollector.Collect() if err != nil { return fmt.Errorf("failed to collect DirectoryServices (AD) metrics: %w", err) } - adData, ok := data["NTDS"] + data, ok := perfData["NTDS"] if !ok { return errors.New("perflib query for DirectoryServices (AD) returned empty result set") @@ -1398,199 +671,199 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric( c.addressBookOperationsTotal, prometheus.CounterValue, - adData[abANRPerSec].FirstValue, + data[abANRPerSec].FirstValue, "ambiguous_name_resolution", ) ch <- prometheus.MustNewConstMetric( c.addressBookOperationsTotal, prometheus.CounterValue, - adData[abBrowsesPerSec].FirstValue, + data[abBrowsesPerSec].FirstValue, "browse", ) ch <- prometheus.MustNewConstMetric( c.addressBookOperationsTotal, prometheus.CounterValue, - adData[abMatchesPerSec].FirstValue, + data[abMatchesPerSec].FirstValue, "find", ) ch <- prometheus.MustNewConstMetric( c.addressBookOperationsTotal, prometheus.CounterValue, - adData[abPropertyReadsPerSec].FirstValue, + data[abPropertyReadsPerSec].FirstValue, "property_read", ) ch <- prometheus.MustNewConstMetric( c.addressBookOperationsTotal, prometheus.CounterValue, - adData[abSearchesPerSec].FirstValue, + data[abSearchesPerSec].FirstValue, "search", ) ch <- prometheus.MustNewConstMetric( c.addressBookOperationsTotal, prometheus.CounterValue, - adData[abProxyLookupsPerSec].FirstValue, + data[abProxyLookupsPerSec].FirstValue, "proxy_search", ) ch <- prometheus.MustNewConstMetric( c.addressBookClientSessions, prometheus.GaugeValue, - adData[abClientSessions].FirstValue, + data[abClientSessions].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.approximateHighestDistinguishedNameTag, prometheus.GaugeValue, - adData[approximateHighestDNT].FirstValue, + data[approximateHighestDNT].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.atqEstimatedDelaySeconds, prometheus.GaugeValue, - adData[atqEstimatedQueueDelay].FirstValue/1000, + data[atqEstimatedQueueDelay].FirstValue/1000, ) ch <- prometheus.MustNewConstMetric( c.atqOutstandingRequests, prometheus.GaugeValue, - adData[atqOutstandingQueuedRequests].FirstValue, + data[atqOutstandingQueuedRequests].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.atqAverageRequestLatency, prometheus.GaugeValue, - adData[atqRequestLatency].FirstValue, + data[atqRequestLatency].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.atqCurrentThreads, prometheus.GaugeValue, - adData[atqThreadsLDAP].FirstValue, + data[atqThreadsLDAP].FirstValue, "ldap", ) ch <- prometheus.MustNewConstMetric( c.atqCurrentThreads, prometheus.GaugeValue, - adData[atqThreadsOther].FirstValue, + data[atqThreadsOther].FirstValue, "other", ) ch <- prometheus.MustNewConstMetric( c.searchesTotal, prometheus.CounterValue, - adData[baseSearchesPerSec].FirstValue, + data[baseSearchesPerSec].FirstValue, "base", ) ch <- prometheus.MustNewConstMetric( c.searchesTotal, prometheus.CounterValue, - adData[subtreeSearchesPerSec].FirstValue, + data[subtreeSearchesPerSec].FirstValue, "subtree", ) ch <- prometheus.MustNewConstMetric( c.searchesTotal, prometheus.CounterValue, - adData[oneLevelSearchesPerSec].FirstValue, + data[oneLevelSearchesPerSec].FirstValue, "one_level", ) ch <- prometheus.MustNewConstMetric( c.databaseOperationsTotal, prometheus.CounterValue, - adData[databaseAddsPerSec].FirstValue, + data[databaseAddsPerSec].FirstValue, "add", ) ch <- prometheus.MustNewConstMetric( c.databaseOperationsTotal, prometheus.CounterValue, - adData[databaseDeletesPerSec].FirstValue, + data[databaseDeletesPerSec].FirstValue, "delete", ) ch <- prometheus.MustNewConstMetric( c.databaseOperationsTotal, prometheus.CounterValue, - adData[databaseModifiesPerSec].FirstValue, + data[databaseModifiesPerSec].FirstValue, "modify", ) ch <- prometheus.MustNewConstMetric( c.databaseOperationsTotal, prometheus.CounterValue, - adData[databaseRecyclesPerSec].FirstValue, + data[databaseRecyclesPerSec].FirstValue, "recycle", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[digestBindsPerSec].FirstValue, + data[digestBindsPerSec].FirstValue, "digest", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[dsClientBindsPerSec].FirstValue, + data[dsClientBindsPerSec].FirstValue, "ds_client", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[dsServerBindsPerSec].FirstValue, + data[dsServerBindsPerSec].FirstValue, "ds_server", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[externalBindsPerSec].FirstValue, + data[externalBindsPerSec].FirstValue, "external", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[fastBindsPerSec].FirstValue, + data[fastBindsPerSec].FirstValue, "fast", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[negotiatedBindsPerSec].FirstValue, + data[negotiatedBindsPerSec].FirstValue, "negotiate", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[ntlmBindsPerSec].FirstValue, + data[ntlmBindsPerSec].FirstValue, "ntlm", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[simpleBindsPerSec].FirstValue, + data[simpleBindsPerSec].FirstValue, "simple", ) ch <- prometheus.MustNewConstMetric( c.bindsTotal, prometheus.CounterValue, - adData[ldapSuccessfulBindsPerSec].FirstValue, + data[ldapSuccessfulBindsPerSec].FirstValue, "ldap", ) ch <- prometheus.MustNewConstMetric( c.replicationHighestUsn, prometheus.CounterValue, - float64(uint64(adData[draHighestUSNCommittedHighPart].FirstValue)<<32)+adData[draHighestUSNCommittedLowPart].FirstValue, + float64(uint64(data[draHighestUSNCommittedHighPart].FirstValue)<<32)+data[draHighestUSNCommittedLowPart].FirstValue, "committed", ) ch <- prometheus.MustNewConstMetric( c.replicationHighestUsn, prometheus.CounterValue, - float64(uint64(adData[draHighestUSNIssuedHighPart].FirstValue)<<32)+adData[draHighestUSNIssuedLowPart].FirstValue, + float64(uint64(data[draHighestUSNIssuedHighPart].FirstValue)<<32)+data[draHighestUSNIssuedLowPart].FirstValue, "issued", ) ch <- prometheus.MustNewConstMetric( c.interSiteReplicationDataBytesTotal, prometheus.CounterValue, - adData[draInboundBytesCompressedBetweenSitesAfterCompressionPerSec].FirstValue, + data[draInboundBytesCompressedBetweenSitesAfterCompressionPerSec].FirstValue, "inbound", ) - // The pre-compression data size seems to have little value? Skipping for now + // The pre-compression perfData size seems to have little value? Skipping for now // ch <- prometheus.MustNewConstMetric( // c.interSiteReplicationDataBytesTotal, // prometheus.CounterValue, @@ -1600,7 +873,7 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric( c.interSiteReplicationDataBytesTotal, prometheus.CounterValue, - adData[draOutboundBytesCompressedBetweenSitesAfterCompressionPerSec].FirstValue, + data[draOutboundBytesCompressedBetweenSitesAfterCompressionPerSec].FirstValue, "outbound", ) // ch <- prometheus.MustNewConstMetric( @@ -1612,270 +885,270 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric( c.intraSiteReplicationDataBytesTotal, prometheus.CounterValue, - adData[draInboundBytesNotCompressedWithinSitePerSec].FirstValue, + data[draInboundBytesNotCompressedWithinSitePerSec].FirstValue, "inbound", ) ch <- prometheus.MustNewConstMetric( c.intraSiteReplicationDataBytesTotal, prometheus.CounterValue, - adData[draOutboundBytesNotCompressedWithinSitePerSec].FirstValue, + data[draOutboundBytesNotCompressedWithinSitePerSec].FirstValue, "outbound", ) ch <- prometheus.MustNewConstMetric( c.replicationInboundSyncObjectsRemaining, prometheus.GaugeValue, - adData[draInboundFullSyncObjectsRemaining].FirstValue, + data[draInboundFullSyncObjectsRemaining].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationInboundLinkValueUpdatesRemaining, prometheus.GaugeValue, - adData[draInboundLinkValueUpdatesRemainingInPacket].FirstValue, + data[draInboundLinkValueUpdatesRemainingInPacket].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationInboundObjectsUpdatedTotal, prometheus.CounterValue, - adData[draInboundObjectsAppliedPerSec].FirstValue, + data[draInboundObjectsAppliedPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationInboundObjectsFilteredTotal, prometheus.CounterValue, - adData[draInboundObjectsFilteredPerSec].FirstValue, + data[draInboundObjectsFilteredPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationInboundPropertiesUpdatedTotal, prometheus.CounterValue, - adData[draInboundPropertiesAppliedPerSec].FirstValue, + data[draInboundPropertiesAppliedPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationInboundPropertiesFilteredTotal, prometheus.CounterValue, - adData[draInboundPropertiesFilteredPerSec].FirstValue, + data[draInboundPropertiesFilteredPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationPendingOperations, prometheus.GaugeValue, - adData[draPendingReplicationOperations].FirstValue, + data[draPendingReplicationOperations].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationPendingSynchronizations, prometheus.GaugeValue, - adData[draPendingReplicationSynchronizations].FirstValue, + data[draPendingReplicationSynchronizations].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationSyncRequestsTotal, prometheus.CounterValue, - adData[draSyncRequestsMade].FirstValue, + data[draSyncRequestsMade].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationSyncRequestsSuccessTotal, prometheus.CounterValue, - adData[draSyncRequestsSuccessful].FirstValue, + data[draSyncRequestsSuccessful].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.replicationSyncRequestsSchemaMismatchFailureTotal, prometheus.CounterValue, - adData[draSyncFailuresOnSchemaMismatch].FirstValue, + data[draSyncFailuresOnSchemaMismatch].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.nameTranslationsTotal, prometheus.CounterValue, - adData[dsClientNameTranslationsPerSec].FirstValue, + data[dsClientNameTranslationsPerSec].FirstValue, "client", ) ch <- prometheus.MustNewConstMetric( c.nameTranslationsTotal, prometheus.CounterValue, - adData[dsServerNameTranslationsPerSec].FirstValue, + data[dsServerNameTranslationsPerSec].FirstValue, "server", ) ch <- prometheus.MustNewConstMetric( c.changeMonitorsRegistered, prometheus.GaugeValue, - adData[dsMonitorListSize].FirstValue, + data[dsMonitorListSize].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.changeMonitorUpdatesPending, prometheus.GaugeValue, - adData[dsNotifyQueueSize].FirstValue, + data[dsNotifyQueueSize].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.nameCacheHitsTotal, prometheus.CounterValue, - adData[dsNameCacheHitRate].FirstValue, + data[dsNameCacheHitRate].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.nameCacheLookupsTotal, prometheus.CounterValue, - adData[dsNameCacheHitRate].SecondValue, + data[dsNameCacheHitRate].SecondValue, ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentReadsFromDRA].FirstValue, + data[dsPercentReadsFromDRA].FirstValue, "read", "replication_agent", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentReadsFromKCC].FirstValue, + data[dsPercentReadsFromKCC].FirstValue, "read", "knowledge_consistency_checker", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentReadsFromLSA].FirstValue, + data[dsPercentReadsFromLSA].FirstValue, "read", "local_security_authority", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentReadsFromNSPI].FirstValue, + data[dsPercentReadsFromNSPI].FirstValue, "read", "name_service_provider_interface", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentReadsFromNTDSAPI].FirstValue, + data[dsPercentReadsFromNTDSAPI].FirstValue, "read", "directory_service_api", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentReadsFromSAM].FirstValue, + data[dsPercentReadsFromSAM].FirstValue, "read", "security_account_manager", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentReadsOther].FirstValue, + data[dsPercentReadsOther].FirstValue, "read", "other", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromDRA].FirstValue, + data[dsPercentSearchesFromDRA].FirstValue, "search", "replication_agent", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromKCC].FirstValue, + data[dsPercentSearchesFromKCC].FirstValue, "search", "knowledge_consistency_checker", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromLDAP].FirstValue, + data[dsPercentSearchesFromLDAP].FirstValue, "search", "ldap", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromLSA].FirstValue, + data[dsPercentSearchesFromLSA].FirstValue, "search", "local_security_authority", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromNSPI].FirstValue, + data[dsPercentSearchesFromNSPI].FirstValue, "search", "name_service_provider_interface", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromNTDSAPI].FirstValue, + data[dsPercentSearchesFromNTDSAPI].FirstValue, "search", "directory_service_api", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromSAM].FirstValue, + data[dsPercentSearchesFromSAM].FirstValue, "search", "security_account_manager", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesOther].FirstValue, + data[dsPercentSearchesOther].FirstValue, "search", "other", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentWritesFromDRA].FirstValue, + data[dsPercentWritesFromDRA].FirstValue, "write", "replication_agent", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentWritesFromKCC].FirstValue, + data[dsPercentWritesFromKCC].FirstValue, "write", "knowledge_consistency_checker", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentWritesFromLDAP].FirstValue, + data[dsPercentWritesFromLDAP].FirstValue, "write", "ldap", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentSearchesFromLSA].FirstValue, + data[dsPercentSearchesFromLSA].FirstValue, "write", "local_security_authority", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentWritesFromNSPI].FirstValue, + data[dsPercentWritesFromNSPI].FirstValue, "write", "name_service_provider_interface", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentWritesFromNTDSAPI].FirstValue, + data[dsPercentWritesFromNTDSAPI].FirstValue, "write", "directory_service_api", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentWritesFromSAM].FirstValue, + data[dsPercentWritesFromSAM].FirstValue, "write", "security_account_manager", ) ch <- prometheus.MustNewConstMetric( c.directoryOperationsTotal, prometheus.CounterValue, - adData[dsPercentWritesOther].FirstValue, + data[dsPercentWritesOther].FirstValue, "write", "other", ) @@ -1883,207 +1156,207 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric( c.directorySearchSubOperationsTotal, prometheus.CounterValue, - adData[dsSearchSubOperationsPerSec].FirstValue, + data[dsSearchSubOperationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.securityDescriptorPropagationEventsTotal, prometheus.CounterValue, - adData[dsSecurityDescriptorSubOperationsPerSec].FirstValue, + data[dsSecurityDescriptorSubOperationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.securityDescriptorPropagationEventsQueued, prometheus.GaugeValue, - adData[dsSecurityDescriptorPropagationsEvents].FirstValue, + data[dsSecurityDescriptorPropagationsEvents].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.securityDescriptorPropagationAccessWaitTotalSeconds, prometheus.GaugeValue, - adData[dsSecurityDescriptorPropagatorAverageExclusionTime].FirstValue, + data[dsSecurityDescriptorPropagatorAverageExclusionTime].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.securityDescriptorPropagationItemsQueuedTotal, prometheus.CounterValue, - adData[dsSecurityDescriptorPropagatorRuntimeQueue].FirstValue, + data[dsSecurityDescriptorPropagatorRuntimeQueue].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.directoryServiceThreads, prometheus.GaugeValue, - adData[dsThreadsInUse].FirstValue, + data[dsThreadsInUse].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.ldapClosedConnectionsTotal, prometheus.CounterValue, - adData[ldapClosedConnectionsPerSec].FirstValue, + data[ldapClosedConnectionsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.ldapOpenedConnectionsTotal, prometheus.CounterValue, - adData[ldapNewConnectionsPerSec].FirstValue, + data[ldapNewConnectionsPerSec].FirstValue, "ldap", ) ch <- prometheus.MustNewConstMetric( c.ldapOpenedConnectionsTotal, prometheus.CounterValue, - adData[ldapNewSSLConnectionsPerSec].FirstValue, + data[ldapNewSSLConnectionsPerSec].FirstValue, "ldaps", ) ch <- prometheus.MustNewConstMetric( c.ldapActiveThreads, prometheus.GaugeValue, - adData[ldapActiveThreads].FirstValue, + data[ldapActiveThreads].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.ldapLastBindTimeSeconds, prometheus.GaugeValue, - adData[ldapBindTime].FirstValue/1000, + data[ldapBindTime].FirstValue/1000, ) ch <- prometheus.MustNewConstMetric( c.ldapSearchesTotal, prometheus.CounterValue, - adData[ldapSearchesPerSec].FirstValue, + data[ldapSearchesPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.ldapUdpOperationsTotal, prometheus.CounterValue, - adData[ldapUDPOperationsPerSec].FirstValue, + data[ldapUDPOperationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.ldapWritesTotal, prometheus.CounterValue, - adData[ldapWritesPerSec].FirstValue, + data[ldapWritesPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.ldapClientSessions, prometheus.GaugeValue, - adData[ldapClientSessions].FirstValue, + data[ldapClientSessions].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.linkValuesCleanedTotal, prometheus.CounterValue, - adData[linkValuesCleanedPerSec].FirstValue, + data[linkValuesCleanedPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.phantomObjectsCleanedTotal, prometheus.CounterValue, - adData[phantomsCleanedPerSec].FirstValue, + data[phantomsCleanedPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.phantomObjectsVisitedTotal, prometheus.CounterValue, - adData[phantomsVisitedPerSec].FirstValue, + data[phantomsVisitedPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samGroupMembershipEvaluationsTotal, prometheus.CounterValue, - adData[samGlobalGroupMembershipEvaluationsPerSec].FirstValue, + data[samGlobalGroupMembershipEvaluationsPerSec].FirstValue, "global", ) ch <- prometheus.MustNewConstMetric( c.samGroupMembershipEvaluationsTotal, prometheus.CounterValue, - adData[samDomainLocalGroupMembershipEvaluationsPerSec].FirstValue, + data[samDomainLocalGroupMembershipEvaluationsPerSec].FirstValue, "domain_local", ) ch <- prometheus.MustNewConstMetric( c.samGroupMembershipEvaluationsTotal, prometheus.CounterValue, - adData[samUniversalGroupMembershipEvaluationsPerSec].FirstValue, + data[samUniversalGroupMembershipEvaluationsPerSec].FirstValue, "universal", ) ch <- prometheus.MustNewConstMetric( c.samGroupMembershipGlobalCatalogEvaluationsTotal, prometheus.CounterValue, - adData[samGCEvaluationsPerSec].FirstValue, + data[samGCEvaluationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samGroupMembershipEvaluationsNonTransitiveTotal, prometheus.CounterValue, - adData[samNonTransitiveMembershipEvaluationsPerSec].FirstValue, + data[samNonTransitiveMembershipEvaluationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samGroupMembershipEvaluationsTransitiveTotal, prometheus.CounterValue, - adData[samTransitiveMembershipEvaluationsPerSec].FirstValue, + data[samTransitiveMembershipEvaluationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samGroupEvaluationLatency, prometheus.GaugeValue, - adData[samAccountGroupEvaluationLatency].FirstValue, + data[samAccountGroupEvaluationLatency].FirstValue, "account_group", ) ch <- prometheus.MustNewConstMetric( c.samGroupEvaluationLatency, prometheus.GaugeValue, - adData[samResourceGroupEvaluationLatency].FirstValue, + data[samResourceGroupEvaluationLatency].FirstValue, "resource_group", ) ch <- prometheus.MustNewConstMetric( c.samComputerCreationRequestsTotal, prometheus.CounterValue, - adData[samSuccessfulComputerCreationsPerSecIncludesAllRequests].FirstValue, + data[samSuccessfulComputerCreationsPerSecIncludesAllRequests].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samComputerCreationSuccessfulRequestsTotal, prometheus.CounterValue, - adData[samMachineCreationAttemptsPerSec].FirstValue, + data[samMachineCreationAttemptsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samUserCreationRequestsTotal, prometheus.CounterValue, - adData[samUserCreationAttemptsPerSec].FirstValue, + data[samUserCreationAttemptsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samUserCreationSuccessfulRequestsTotal, prometheus.CounterValue, - adData[samSuccessfulUserCreationsPerSec].FirstValue, + data[samSuccessfulUserCreationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samQueryDisplayRequestsTotal, prometheus.CounterValue, - adData[samDisplayInformationQueriesPerSec].FirstValue, + data[samDisplayInformationQueriesPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samEnumerationsTotal, prometheus.CounterValue, - adData[samEnumerationsPerSec].FirstValue, + data[samEnumerationsPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samMembershipChangesTotal, prometheus.CounterValue, - adData[samMembershipChangesPerSec].FirstValue, + data[samMembershipChangesPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.samPasswordChangesTotal, prometheus.CounterValue, - adData[samPasswordChangesPerSec].FirstValue, + data[samPasswordChangesPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.tombstonesObjectsCollectedTotal, prometheus.CounterValue, - adData[tombstonesGarbageCollectedPerSec].FirstValue, + data[tombstonesGarbageCollectedPerSec].FirstValue, ) ch <- prometheus.MustNewConstMetric( c.tombstonesObjectsVisitedTotal, prometheus.CounterValue, - adData[tombstonesVisitedPerSec].FirstValue, + data[tombstonesVisitedPerSec].FirstValue, ) return nil diff --git a/internal/collector/adcs/adcs.go b/internal/collector/adcs/adcs.go index 16f6f212..d484793a 100644 --- a/internal/collector/adcs/adcs.go +++ b/internal/collector/adcs/adcs.go @@ -9,7 +9,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/utils" "github.com/prometheus/client_golang/prometheus" @@ -25,7 +25,7 @@ var ConfigDefaults = Config{} type Collector struct { config Config - perfDataCollector *perfdata.Collector + perfDataCollector perfdata.Collector challengeResponseProcessingTime *prometheus.Desc challengeResponsesPerSecond *prometheus.Desc @@ -94,7 +94,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) 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 { 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") } - err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, logger) + err := v1.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, logger) if err != nil { return err } diff --git a/internal/collector/adfs/adfs.go b/internal/collector/adfs/adfs.go index 608fa400..a481ead2 100644 --- a/internal/collector/adfs/adfs.go +++ b/internal/collector/adfs/adfs.go @@ -12,7 +12,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/utils" "github.com/prometheus/client_golang/prometheus" @@ -28,7 +28,7 @@ var ConfigDefaults = Config{} type Collector struct { config Config - perfDataCollector *perfdata.Collector + perfDataCollector perfdata.Collector adLoginConnectionFailures *prometheus.Desc artifactDBFailures *prometheus.Desc @@ -157,7 +157,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) 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 { 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 { var adfsData []perflibADFS - err := perflib.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, logger) + err := v1.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, logger) if err != nil { return err } diff --git a/internal/collector/cache/cache.go b/internal/collector/cache/cache.go index 8fe245a6..051c6946 100644 --- a/internal/collector/cache/cache.go +++ b/internal/collector/cache/cache.go @@ -9,7 +9,8 @@ import ( "github.com/alecthomas/kingpin/v2" "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/utils" "github.com/prometheus/client_golang/prometheus" @@ -26,7 +27,7 @@ var ConfigDefaults = Config{} type Collector struct { config Config - perfDataCollector *perfdata.Collector + perfDataCollector perfdata.Collector asyncCopyReadsTotal *prometheus.Desc asyncDataMapsTotal *prometheus.Desc @@ -127,7 +128,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) 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 { 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 { 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 } @@ -523,7 +524,7 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error { return fmt.Errorf("failed to collect Cache metrics: %w", err) } - cacheData, ok := data["*"] + cacheData, ok := data[perftypes.EmptyInstance] if !ok { return errors.New("perflib query for Cache returned empty result set") diff --git a/internal/collector/container/container.go b/internal/collector/container/container.go index 478b88f0..b6b53650 100644 --- a/internal/collector/container/container.go +++ b/internal/collector/container/container.go @@ -10,7 +10,7 @@ import ( "github.com/Microsoft/hcsshim" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -325,19 +325,19 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M ch <- prometheus.MustNewConstMetric( c.runtimeTotal, prometheus.CounterValue, - float64(containerStats.Processor.TotalRuntime100ns)*perflib.TicksToSecondScaleFactor, + float64(containerStats.Processor.TotalRuntime100ns)*perftypes.TicksToSecondScaleFactor, containerIdWithPrefix, ) ch <- prometheus.MustNewConstMetric( c.runtimeUser, prometheus.CounterValue, - float64(containerStats.Processor.RuntimeUser100ns)*perflib.TicksToSecondScaleFactor, + float64(containerStats.Processor.RuntimeUser100ns)*perftypes.TicksToSecondScaleFactor, containerIdWithPrefix, ) ch <- prometheus.MustNewConstMetric( c.runtimeKernel, prometheus.CounterValue, - float64(containerStats.Processor.RuntimeKernel100ns)*perflib.TicksToSecondScaleFactor, + float64(containerStats.Processor.RuntimeKernel100ns)*perftypes.TicksToSecondScaleFactor, containerIdWithPrefix, ) ch <- prometheus.MustNewConstMetric( diff --git a/internal/collector/cpu/cpu.go b/internal/collector/cpu/cpu.go index 75ddef1b..e48ae8fd 100644 --- a/internal/collector/cpu/cpu.go +++ b/internal/collector/cpu/cpu.go @@ -9,7 +9,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/utils" "github.com/prometheus/client_golang/prometheus" @@ -25,7 +25,7 @@ var ConfigDefaults = Config{} type Collector struct { config Config - perfDataCollector *perfdata.Collector + perfDataCollector perfdata.Collector processorRTCValues map[string]cpuCounter processorMPerfValues map[string]cpuCounter @@ -113,7 +113,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) 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 { 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 { 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 { return err } diff --git a/internal/collector/dfsr/dfsr.go b/internal/collector/dfsr/dfsr.go index d8defe3d..95df8235 100644 --- a/internal/collector/dfsr/dfsr.go +++ b/internal/collector/dfsr/dfsr.go @@ -11,7 +11,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/utils" "github.com/prometheus/client_golang/prometheus" @@ -32,9 +32,9 @@ var ConfigDefaults = Config{ type Collector struct { config Config - perfDataCollectorConnection *perfdata.Collector - perfDataCollectorFolder *perfdata.Collector - perfDataCollectorVolume *perfdata.Collector + perfDataCollectorConnection perfdata.Collector + perfDataCollectorFolder perfdata.Collector + perfDataCollectorVolume perfdata.Collector // connection source connectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc @@ -189,7 +189,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error { 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 { 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, } - 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 { 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, } - 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 { 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 { 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 } @@ -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 { 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 } @@ -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 { 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 } diff --git a/internal/collector/dhcp/dhcp.go b/internal/collector/dhcp/dhcp.go index 3edf90d0..7806f030 100644 --- a/internal/collector/dhcp/dhcp.go +++ b/internal/collector/dhcp/dhcp.go @@ -6,7 +6,7 @@ import ( "log/slog" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -268,7 +268,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch 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 } diff --git a/internal/collector/exchange/exchange.go b/internal/collector/exchange/exchange.go index d2f80a0e..a23349d6 100644 --- a/internal/collector/exchange/exchange.go +++ b/internal/collector/exchange/exchange.go @@ -9,7 +9,7 @@ import ( "strings" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -275,7 +275,7 @@ func (c *Collector) collectADAccessProcesses(ctx *types.ScrapeContext, logger *s 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 } @@ -338,7 +338,7 @@ func (c *Collector) collectAvailabilityService(ctx *types.ScrapeContext, logger 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 } @@ -370,7 +370,7 @@ func (c *Collector) collectHTTPProxy(ctx *types.ScrapeContext, logger *slog.Logg 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 } @@ -428,7 +428,7 @@ func (c *Collector) collectOWA(ctx *types.ScrapeContext, logger *slog.Logger, ch 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 } @@ -460,7 +460,7 @@ func (c *Collector) collectActiveSync(ctx *types.ScrapeContext, logger *slog.Log 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 } @@ -500,7 +500,7 @@ func (c *Collector) collectRPC(ctx *types.ScrapeContext, logger *slog.Logger, ch 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 } @@ -559,7 +559,7 @@ func (c *Collector) collectTransportQueues(ctx *types.ScrapeContext, logger *slo 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 } @@ -637,7 +637,7 @@ func (c *Collector) collectWorkloadManagementWorkloads(ctx *types.ScrapeContext, 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 } @@ -691,7 +691,7 @@ func (c *Collector) collectAutoDiscover(ctx *types.ScrapeContext, logger *slog.L 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 } @@ -716,7 +716,7 @@ func (c *Collector) collectMapiHttpEmsmdb(ctx *types.ScrapeContext, logger *slog 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 } diff --git a/internal/collector/iis/iis.go b/internal/collector/iis/iis.go index 17edab5e..9ef80470 100644 --- a/internal/collector/iis/iis.go +++ b/internal/collector/iis/iis.go @@ -10,7 +10,7 @@ import ( "strings" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -1073,7 +1073,7 @@ func (c *Collector) collectWebService(ctx *types.ScrapeContext, logger *slog.Log 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 } @@ -1368,7 +1368,7 @@ func (c *Collector) collectAPP_POOL_WAS(ctx *types.ScrapeContext, logger *slog.L 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 } @@ -1548,7 +1548,7 @@ func (c *Collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, logger *slog.Log 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 } @@ -1807,7 +1807,7 @@ func (c *Collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, logger *slog.Log if c.iisVersion.major >= 8 { 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 } @@ -1950,7 +1950,7 @@ func (c *Collector) collectWebServiceCache(ctx *types.ScrapeContext, logger *slo 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 } diff --git a/internal/collector/logical_disk/logical_disk.go b/internal/collector/logical_disk/logical_disk.go index 05ab29b4..7bba3eaf 100644 --- a/internal/collector/logical_disk/logical_disk.go +++ b/internal/collector/logical_disk/logical_disk.go @@ -12,7 +12,8 @@ import ( "strings" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -307,7 +308,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch 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 } @@ -354,14 +355,14 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch ch <- prometheus.MustNewConstMetric( c.avgReadQueue, prometheus.GaugeValue, - volume.AvgDiskReadQueueLength*perflib.TicksToSecondScaleFactor, + volume.AvgDiskReadQueueLength*perftypes.TicksToSecondScaleFactor, volume.Name, ) ch <- prometheus.MustNewConstMetric( c.avgWriteQueue, prometheus.GaugeValue, - volume.AvgDiskWriteQueueLength*perflib.TicksToSecondScaleFactor, + volume.AvgDiskWriteQueueLength*perftypes.TicksToSecondScaleFactor, volume.Name, ) @@ -438,21 +439,21 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch ch <- prometheus.MustNewConstMetric( c.readLatency, prometheus.CounterValue, - volume.AvgDiskSecPerRead*perflib.TicksToSecondScaleFactor, + volume.AvgDiskSecPerRead*perftypes.TicksToSecondScaleFactor, volume.Name, ) ch <- prometheus.MustNewConstMetric( c.writeLatency, prometheus.CounterValue, - volume.AvgDiskSecPerWrite*perflib.TicksToSecondScaleFactor, + volume.AvgDiskSecPerWrite*perftypes.TicksToSecondScaleFactor, volume.Name, ) ch <- prometheus.MustNewConstMetric( c.readWriteLatency, prometheus.CounterValue, - volume.AvgDiskSecPerTransfer*perflib.TicksToSecondScaleFactor, + volume.AvgDiskSecPerTransfer*perftypes.TicksToSecondScaleFactor, volume.Name, ) } diff --git a/internal/collector/memory/memory.go b/internal/collector/memory/memory.go index 1283324d..a08fe277 100644 --- a/internal/collector/memory/memory.go +++ b/internal/collector/memory/memory.go @@ -12,7 +12,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -418,7 +418,7 @@ func (c *Collector) collectPerformanceData(ctx *types.ScrapeContext, logger *slo 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 } diff --git a/internal/collector/mssql/mssql.go b/internal/collector/mssql/mssql.go index 1690095f..271173f3 100644 --- a/internal/collector/mssql/mssql.go +++ b/internal/collector/mssql/mssql.go @@ -13,7 +13,7 @@ import ( "time" "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/client_golang/prometheus" "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)) - 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 } @@ -2441,7 +2441,7 @@ func (c *Collector) collectAvailabilityReplica(ctx *types.ScrapeContext, logger 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } @@ -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)) - 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 } diff --git a/internal/collector/net/net.go b/internal/collector/net/net.go index 5dafc10b..01a025d7 100644 --- a/internal/collector/net/net.go +++ b/internal/collector/net/net.go @@ -14,7 +14,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/utils" "github.com/prometheus/client_golang/prometheus" @@ -43,7 +43,7 @@ var ConfigDefaults = Config{ type Collector struct { config Config - perfDataCollector *perfdata.Collector + perfDataCollector perfdata.Collector bytesReceivedTotal *prometheus.Desc bytesSentTotal *prometheus.Desc @@ -169,7 +169,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) 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 { 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 { 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 } diff --git a/internal/collector/os/os.go b/internal/collector/os/os.go index 5cc727d7..e0acaf0d 100644 --- a/internal/collector/os/os.go +++ b/internal/collector/os/os.go @@ -16,7 +16,7 @@ import ( "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/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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -412,7 +412,7 @@ func (c *Collector) collectPaging(ctx *types.ScrapeContext, logger *slog.Logger, } 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 } diff --git a/internal/collector/perfdata/perfdata.go b/internal/collector/perfdata/perfdata.go index e07c74fd..b0e6b263 100644 --- a/internal/collector/perfdata/perfdata.go +++ b/internal/collector/perfdata/perfdata.go @@ -12,14 +12,13 @@ import ( "github.com/alecthomas/kingpin/v2" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" ) -const ( - Name = "perfdata" -) +const Name = "perfdata" type Config struct { 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.") 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 { - return fmt.Errorf("failed to create pdh collector: %w", err) + return fmt.Errorf("failed to create v2 collector: %w", err) } if object.InstanceLabel == "" { @@ -136,7 +135,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error { for instance, counters := range data { for counter, value := range counters { var labels prometheus.Labels - if instance != perfdata.EmptyInstance { + if instance != perftypes.EmptyInstance { labels = prometheus.Labels{object.InstanceLabel: instance} } diff --git a/internal/collector/perfdata/types.go b/internal/collector/perfdata/types.go index 1b441490..3ee0d892 100644 --- a/internal/collector/perfdata/types.go +++ b/internal/collector/perfdata/types.go @@ -1,8 +1,6 @@ package perfdata -import ( - "github.com/prometheus-community/windows_exporter/internal/perfdata" -) +import "github.com/prometheus-community/windows_exporter/internal/perfdata" type Object struct { Object string `json:"object" yaml:"object"` @@ -10,7 +8,7 @@ type Object struct { Counters map[string]Counter `json:"counters" yaml:"counters"` InstanceLabel string `json:"instance_label" yaml:"instance_label"` //nolint:tagliatelle - collector *perfdata.Collector + collector perfdata.Collector } type Counter struct { diff --git a/internal/collector/physical_disk/physical_disk.go b/internal/collector/physical_disk/physical_disk.go index d0eae209..e251088f 100644 --- a/internal/collector/physical_disk/physical_disk.go +++ b/internal/collector/physical_disk/physical_disk.go @@ -9,7 +9,8 @@ import ( "strings" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -240,7 +241,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch 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 } @@ -321,21 +322,21 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch ch <- prometheus.MustNewConstMetric( c.readLatency, prometheus.CounterValue, - disk.AvgDiskSecPerRead*perflib.TicksToSecondScaleFactor, + disk.AvgDiskSecPerRead*perftypes.TicksToSecondScaleFactor, disk_number, ) ch <- prometheus.MustNewConstMetric( c.writeLatency, prometheus.CounterValue, - disk.AvgDiskSecPerWrite*perflib.TicksToSecondScaleFactor, + disk.AvgDiskSecPerWrite*perftypes.TicksToSecondScaleFactor, disk_number, ) ch <- prometheus.MustNewConstMetric( c.readWriteLatency, prometheus.CounterValue, - disk.AvgDiskSecPerTransfer*perflib.TicksToSecondScaleFactor, + disk.AvgDiskSecPerTransfer*perftypes.TicksToSecondScaleFactor, disk_number, ) } diff --git a/internal/collector/process/process.go b/internal/collector/process/process.go index def1dc61..d5cc6618 100644 --- a/internal/collector/process/process.go +++ b/internal/collector/process/process.go @@ -13,7 +13,8 @@ import ( "github.com/alecthomas/kingpin/v2" "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/utils" "github.com/prometheus/client_golang/prometheus" @@ -24,24 +25,22 @@ import ( const Name = "process" type Config struct { - ProcessInclude *regexp.Regexp `yaml:"process_include"` - ProcessExclude *regexp.Regexp `yaml:"process_exclude"` - EnableWorkerProcess bool `yaml:"enable_iis_worker_process"` //nolint:tagliatelle - PerfCounterInstances []string `yaml:"perf_counter_instances"` + ProcessInclude *regexp.Regexp `yaml:"process_include"` + ProcessExclude *regexp.Regexp `yaml:"process_exclude"` + EnableWorkerProcess bool `yaml:"enable_iis_worker_process"` //nolint:tagliatelle } var ConfigDefaults = Config{ - ProcessInclude: types.RegExpAny, - ProcessExclude: types.RegExpEmpty, - EnableWorkerProcess: false, - PerfCounterInstances: []string{"*"}, + ProcessInclude: types.RegExpAny, + ProcessExclude: types.RegExpEmpty, + EnableWorkerProcess: false, } type Collector struct { config Config wmiClient *wmi.Client - perfDataCollector *perfdata.Collector + perfDataCollector perfdata.Collector lookupCache map[string]string @@ -76,10 +75,6 @@ func New(config *Config) *Collector { config.ProcessInclude = ConfigDefaults.ProcessInclude } - if config.PerfCounterInstances == nil { - config.PerfCounterInstances = ConfigDefaults.PerfCounterInstances - } - c := &Collector{ config: *config, } @@ -92,7 +87,7 @@ func NewWithFlags(app *kingpin.Application) *Collector { config: ConfigDefaults, } - var processExclude, processInclude, perfCounterInstances string + var processExclude, processInclude string app.Flag( "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.", ).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 { - c.config.PerfCounterInstances = strings.Split(perfCounterInstances, ",") - var err error 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 - c.perfDataCollector, err = perfdata.NewCollector("Process V2", c.config.PerfCounterInstances, counters) - if errors.Is(err, perfdata.NewPdhError(perfdata.PdhCstatusNoObject)) { + c.perfDataCollector, err = perfdata.NewCollector(perfdata.V2, "Process V2", perfdata.AllInstances, counters) + if errors.Is(err, v2.NewPdhError(v2.PdhCstatusNoObject)) { 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 { @@ -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 { data := make([]perflibProcess, 0) - err := perflib.UnmarshalObject(ctx.PerfObjects["Process"], &data, logger) + err := v1.UnmarshalObject(ctx.PerfObjects["Process"], &data, logger) if err != nil { return err } diff --git a/internal/collector/remote_fx/remote_fx.go b/internal/collector/remote_fx/remote_fx.go index 348feb4b..92921bca 100644 --- a/internal/collector/remote_fx/remote_fx.go +++ b/internal/collector/remote_fx/remote_fx.go @@ -7,7 +7,7 @@ import ( "strings" "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/utils" "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)) 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 { return err } @@ -366,7 +366,7 @@ func (c *Collector) collectRemoteFXGraphicsCounters(ctx *types.ScrapeContext, lo logger = logger.With(slog.String("collector", Name)) 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 { return err } diff --git a/internal/collector/smb/smb.go b/internal/collector/smb/smb.go index 5f2023b5..dd97598a 100644 --- a/internal/collector/smb/smb.go +++ b/internal/collector/smb/smb.go @@ -7,7 +7,7 @@ import ( "strings" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -100,7 +100,7 @@ func (c *Collector) collectServerShares(ctx *types.ScrapeContext, logger *slog.L 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 } diff --git a/internal/collector/smbclient/smbclient.go b/internal/collector/smbclient/smbclient.go index f27f3ff0..2b579e40 100644 --- a/internal/collector/smbclient/smbclient.go +++ b/internal/collector/smbclient/smbclient.go @@ -7,7 +7,8 @@ import ( "strings" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -223,7 +224,7 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L 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 } @@ -239,7 +240,7 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L ch <- prometheus.MustNewConstMetric( c.requestQueueSecsTotal, prometheus.CounterValue, - instance.AvgDataQueueLength*perflib.TicksToSecondScaleFactor, + instance.AvgDataQueueLength*perftypes.TicksToSecondScaleFactor, serverValue, shareValue, ) @@ -247,28 +248,28 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L ch <- prometheus.MustNewConstMetric( c.readRequestQueueSecsTotal, prometheus.CounterValue, - instance.AvgReadQueueLength*perflib.TicksToSecondScaleFactor, + instance.AvgReadQueueLength*perftypes.TicksToSecondScaleFactor, serverValue, shareValue, ) ch <- prometheus.MustNewConstMetric( c.readSecsTotal, prometheus.CounterValue, - instance.AvgSecPerRead*perflib.TicksToSecondScaleFactor, + instance.AvgSecPerRead*perftypes.TicksToSecondScaleFactor, serverValue, shareValue, ) ch <- prometheus.MustNewConstMetric( c.writeSecsTotal, prometheus.CounterValue, - instance.AvgSecPerWrite*perflib.TicksToSecondScaleFactor, + instance.AvgSecPerWrite*perftypes.TicksToSecondScaleFactor, serverValue, shareValue, ) ch <- prometheus.MustNewConstMetric( c.requestSecs, prometheus.CounterValue, - instance.AvgSecPerDataRequest*perflib.TicksToSecondScaleFactor, + instance.AvgSecPerDataRequest*perftypes.TicksToSecondScaleFactor, serverValue, shareValue, ) @@ -276,7 +277,7 @@ func (c *Collector) collectClientShares(ctx *types.ScrapeContext, logger *slog.L ch <- prometheus.MustNewConstMetric( c.writeRequestQueueSecsTotal, prometheus.CounterValue, - instance.AvgWriteQueueLength*perflib.TicksToSecondScaleFactor, + instance.AvgWriteQueueLength*perftypes.TicksToSecondScaleFactor, serverValue, shareValue, ) diff --git a/internal/collector/smtp/smtp.go b/internal/collector/smtp/smtp.go index 95c2e7c6..4edfd1d0 100644 --- a/internal/collector/smtp/smtp.go +++ b/internal/collector/smtp/smtp.go @@ -8,7 +8,7 @@ import ( "regexp" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -470,7 +470,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch 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 } diff --git a/internal/collector/system/system.go b/internal/collector/system/system.go index 05f6e7bc..6465debb 100644 --- a/internal/collector/system/system.go +++ b/internal/collector/system/system.go @@ -7,7 +7,7 @@ import ( "log/slog" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -147,7 +147,7 @@ func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch ch 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 } diff --git a/internal/collector/tcp/tcp.go b/internal/collector/tcp/tcp.go index b44421a7..24b8d435 100644 --- a/internal/collector/tcp/tcp.go +++ b/internal/collector/tcp/tcp.go @@ -11,6 +11,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/perftypes" "github.com/prometheus-community/windows_exporter/internal/types" "github.com/prometheus/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -34,8 +35,8 @@ var ConfigDefaults = Config{ type Collector struct { config Config - perfDataCollector4 *perfdata.Collector - perfDataCollector6 *perfdata.Collector + perfDataCollector4 perfdata.Collector + perfDataCollector6 perfdata.Collector connectionFailures *prometheus.Desc connectionsActive *prometheus.Desc @@ -114,12 +115,12 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) 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 { 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 { 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) } - c.writeTCPCounters(ch, data[perfdata.EmptyInstance], []string{"ipv4"}) + c.writeTCPCounters(ch, data[perftypes.EmptyInstance], []string{"ipv4"}) data, err = c.perfDataCollector6.Collect() if err != nil { 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 } -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( c.connectionFailures, prometheus.CounterValue, diff --git a/internal/collector/terminal_services/terminal_services.go b/internal/collector/terminal_services/terminal_services.go index 0a119720..31b8d573 100644 --- a/internal/collector/terminal_services/terminal_services.go +++ b/internal/collector/terminal_services/terminal_services.go @@ -11,7 +11,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -275,7 +275,7 @@ func (c *Collector) collectTSSessionCounters(ctx *types.ScrapeContext, logger *s logger = logger.With(slog.String("collector", Name)) 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 { return err } @@ -403,7 +403,7 @@ func (c *Collector) collectCollectionBrokerPerformanceCounter(ctx *types.ScrapeC logger = logger.With(slog.String("collector", Name)) 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 { return err } diff --git a/internal/collector/time/time.go b/internal/collector/time/time.go index 020cde44..7b0b8487 100644 --- a/internal/collector/time/time.go +++ b/internal/collector/time/time.go @@ -9,7 +9,7 @@ import ( "github.com/alecthomas/kingpin/v2" "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/client_golang/prometheus" "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. - 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 } diff --git a/internal/collector/vmware/vmware.go b/internal/collector/vmware/vmware.go index d8354fff..ba5d0ccf 100644 --- a/internal/collector/vmware/vmware.go +++ b/internal/collector/vmware/vmware.go @@ -7,7 +7,7 @@ import ( "log/slog" "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/client_golang/prometheus" "github.com/yusufpapurcu/wmi" @@ -368,13 +368,13 @@ func (c *Collector) collectCpu(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric( c.cpuStolenTotal, prometheus.CounterValue, - float64(dst[0].CpuStolenMs)*perflib.TicksToSecondScaleFactor, + float64(dst[0].CpuStolenMs)*perftypes.TicksToSecondScaleFactor, ) ch <- prometheus.MustNewConstMetric( c.cpuTimeTotal, prometheus.CounterValue, - float64(dst[0].CpuTimePercents)*perflib.TicksToSecondScaleFactor, + float64(dst[0].CpuTimePercents)*perftypes.TicksToSecondScaleFactor, ) ch <- prometheus.MustNewConstMetric( diff --git a/internal/perfdata/perfdata.go b/internal/perfdata/perfdata.go new file mode 100644 index 00000000..e8ca6267 --- /dev/null +++ b/internal/perfdata/perfdata.go @@ -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 + } +} diff --git a/internal/perfdata/const.go b/internal/perfdata/perftypes/const.go similarity index 97% rename from internal/perfdata/const.go rename to internal/perfdata/perftypes/const.go index c618fd55..83679e88 100644 --- a/internal/perfdata/const.go +++ b/internal/perfdata/perftypes/const.go @@ -1,6 +1,4 @@ -//go:build windows - -package perfdata +package perftypes import "github.com/prometheus/client_golang/prometheus" @@ -57,7 +55,7 @@ const ( 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_LARGE_RAWCOUNT_HEX: prometheus.GaugeValue, PERF_COUNTER_RAWCOUNT: prometheus.GaugeValue, diff --git a/internal/perfdata/perftypes/types.go b/internal/perfdata/perftypes/types.go new file mode 100644 index 00000000..5fd61f9a --- /dev/null +++ b/internal/perfdata/perftypes/types.go @@ -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 +} diff --git a/internal/perflib/LICENSE b/internal/perfdata/v1/LICENSE similarity index 100% rename from internal/perflib/LICENSE rename to internal/perfdata/v1/LICENSE diff --git a/internal/perfdata/v1/collector.go b/internal/perfdata/v1/collector.go new file mode 100644 index 00000000..846ad85e --- /dev/null +++ b/internal/perfdata/v1/collector.go @@ -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() { +} diff --git a/internal/perflib/nametable.go b/internal/perfdata/v1/nametable.go similarity index 93% rename from internal/perflib/nametable.go rename to internal/perfdata/v1/nametable.go index 75065f7d..865b8f78 100644 --- a/internal/perflib/nametable.go +++ b/internal/perfdata/v1/nametable.go @@ -1,4 +1,4 @@ -package perflib +package v1 import ( "bytes" @@ -41,7 +41,7 @@ func (t *NameTable) LookupIndex(str string) uint32 { 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. func QueryNameTable(tableName string) *NameTable { return &NameTable{ diff --git a/internal/perflib/perflib.go b/internal/perfdata/v1/perflib.go similarity index 95% rename from internal/perflib/perflib.go rename to internal/perfdata/v1/perflib.go index 58b650b8..746d6b87 100644 --- a/internal/perflib/perflib.go +++ b/internal/perfdata/v1/perflib.go @@ -1,4 +1,4 @@ -package perflib +package v1 /* 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). 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, but this is, sadly, a rare occurrence. @@ -117,7 +117,6 @@ import ( "fmt" "io" "strings" - "syscall" "unsafe" "golang.org/x/sys/windows" @@ -214,8 +213,7 @@ func queryRawData(query string) ([]byte, error) { for { bufLen := uint32(len(buffer)) - //nolint:forbidigo // Legacy Code - err := syscall.RegQueryValueEx( + err := windows.RegQueryValueEx( windows.HKEY_PERFORMANCE_DATA, name, nil, @@ -223,14 +221,14 @@ func queryRawData(query string) ([]byte, error) { (*byte)(unsafe.Pointer(&buffer[0])), &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) copy(newBuffer, buffer) buffer = newBuffer continue } else if err != nil { - var errNo syscall.Errno //nolint:forbidigo // Legacy Code + var errNo windows.Errno if errors.As(err, &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 } -//nolint:nonamedreturns -func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, valueOffset int64) (value int64) { +func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, valueOffset int64) int64 { /* 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...) @@ -464,12 +461,10 @@ func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, value */ switch counterDef.CounterSize { case 4: - value = int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)])) + return int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)])) case 8: - value = int64(bo.Uint64(buffer[valueOffset:(valueOffset + 8)])) + return int64(bo.Uint64(buffer[valueOffset:(valueOffset + 8)])) default: - value = int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)])) + return int64(bo.Uint32(buffer[valueOffset:(valueOffset + 4)])) } - - return } diff --git a/internal/perflib/perflib_test.go b/internal/perfdata/v1/perflib_test.go similarity index 90% rename from internal/perflib/perflib_test.go rename to internal/perfdata/v1/perflib_test.go index 1ee7ef5c..719172b5 100644 --- a/internal/perflib/perflib_test.go +++ b/internal/perfdata/v1/perflib_test.go @@ -1,4 +1,4 @@ -package perflib +package v1 import ( "testing" diff --git a/internal/perflib/raw_types.go b/internal/perfdata/v1/raw_types.go similarity index 99% rename from internal/perflib/raw_types.go rename to internal/perfdata/v1/raw_types.go index fbd50922..13871180 100644 --- a/internal/perflib/raw_types.go +++ b/internal/perfdata/v1/raw_types.go @@ -1,4 +1,4 @@ -package perflib +package v1 import ( "encoding/binary" diff --git a/internal/perflib/unmarshal.go b/internal/perfdata/v1/unmarshal.go similarity index 86% rename from internal/perflib/unmarshal.go rename to internal/perfdata/v1/unmarshal.go index f4e0b31a..a425c374 100644 --- a/internal/perflib/unmarshal.go +++ b/internal/perfdata/v1/unmarshal.go @@ -1,4 +1,4 @@ -package perflib +package v1 import ( "errors" @@ -6,12 +6,8 @@ import ( "log/slog" "reflect" "strings" -) -// Conversion factors. -const ( - TicksToSecondScaleFactor = 1 / 1e7 - WindowsEpoch = 116444736000000000 + "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes" ) 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 { - case PERF_ELAPSED_TIME: - target.Field(i).SetFloat(float64(ctr.Value-WindowsEpoch) / float64(obj.Frequency)) - case PERF_100NSEC_TIMER, PERF_PRECISION_100NS_TIMER: - target.Field(i).SetFloat(float64(ctr.Value) * TicksToSecondScaleFactor) + case perftypes.PERF_ELAPSED_TIME: + target.Field(i).SetFloat(float64(ctr.Value-perftypes.WindowsEpoch) / float64(obj.Frequency)) + case perftypes.PERF_100NSEC_TIMER, perftypes.PERF_PRECISION_100NS_TIMER: + target.Field(i).SetFloat(float64(ctr.Value) * perftypes.TicksToSecondScaleFactor) default: target.Field(i).SetFloat(float64(ctr.Value)) } diff --git a/internal/perflib/utf16.go b/internal/perfdata/v1/utf16.go similarity index 98% rename from internal/perflib/utf16.go rename to internal/perfdata/v1/utf16.go index 81e2c324..3a298127 100644 --- a/internal/perflib/utf16.go +++ b/internal/perfdata/v1/utf16.go @@ -1,4 +1,4 @@ -package perflib +package v1 import ( "encoding/binary" diff --git a/internal/perflib/utils.go b/internal/perfdata/v1/utils.go similarity index 96% rename from internal/perflib/utils.go rename to internal/perfdata/v1/utils.go index ab101a9c..acb3aa8a 100644 --- a/internal/perflib/utils.go +++ b/internal/perfdata/v1/utils.go @@ -1,4 +1,4 @@ -package perflib +package v1 import ( "strconv" diff --git a/internal/perflib/utils_test.go b/internal/perfdata/v1/utils_test.go similarity index 87% rename from internal/perflib/utils_test.go rename to internal/perfdata/v1/utils_test.go index 82843834..fed423e5 100644 --- a/internal/perflib/utils_test.go +++ b/internal/perfdata/v1/utils_test.go @@ -1,10 +1,12 @@ -package perflib +package v1 import ( "io" "log/slog" "reflect" "testing" + + "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes" ) type simple struct { @@ -38,7 +40,7 @@ func TestUnmarshalPerflib(t *testing.T) { { Def: &PerfCounterDef{ Name: "Something", - CounterType: PERF_COUNTER_COUNTER, + CounterType: perftypes.PERF_COUNTER_COUNTER, }, Value: 123, }, @@ -58,14 +60,14 @@ func TestUnmarshalPerflib(t *testing.T) { { Def: &PerfCounterDef{ Name: "Something", - CounterType: PERF_COUNTER_COUNTER, + CounterType: perftypes.PERF_COUNTER_COUNTER, }, Value: 123, }, { Def: &PerfCounterDef{ Name: "Something Else", - CounterType: PERF_COUNTER_COUNTER, + CounterType: perftypes.PERF_COUNTER_COUNTER, HasSecondValue: true, }, Value: 256, @@ -87,7 +89,7 @@ func TestUnmarshalPerflib(t *testing.T) { { Def: &PerfCounterDef{ Name: "Something", - CounterType: PERF_COUNTER_COUNTER, + CounterType: perftypes.PERF_COUNTER_COUNTER, }, Value: 321, }, @@ -98,7 +100,7 @@ func TestUnmarshalPerflib(t *testing.T) { { Def: &PerfCounterDef{ Name: "Something", - CounterType: PERF_COUNTER_COUNTER, + CounterType: perftypes.PERF_COUNTER_COUNTER, }, Value: 231, }, diff --git a/internal/perfdata/collector.go b/internal/perfdata/v2/collector.go similarity index 82% rename from internal/perfdata/collector.go rename to internal/perfdata/v2/collector.go index 45b5e8fa..8289d737 100644 --- a/internal/perfdata/collector.go +++ b/internal/perfdata/v2/collector.go @@ -1,22 +1,19 @@ //go:build windows -package perfdata +package v2 import ( "errors" "fmt" "strings" - "time" "unsafe" + "github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes" "github.com/prometheus/client_golang/prometheus" "golang.org/x/sys/windows" ) -const EmptyInstance = "------" - type Collector struct { - time time.Time object string counters map[string]Counter handle pdhQueryHandle @@ -30,12 +27,6 @@ type Counter struct { Frequency float64 } -type CounterValues struct { - Type prometheus.ValueType - FirstValue float64 - SecondValue float64 -} - func NewCollector(object string, instances []string, counters []string) (*Collector, error) { var handle pdhQueryHandle @@ -44,7 +35,7 @@ func NewCollector(object string, instances []string, counters []string) (*Collec } if len(instances) == 0 { - instances = []string{EmptyInstance} + instances = []string{perftypes.EmptyInstance} } collector := &Collector{ @@ -127,18 +118,16 @@ func (c *Collector) Describe() map[string]string { 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 { - return map[string]map[string]CounterValues{}, nil + return map[string]map[string]perftypes.CounterValues{}, nil } if ret := PdhCollectQueryData(c.handle); ret != ErrorSuccess { return nil, fmt.Errorf("failed to collect query data: %w", NewPdhError(ret)) } - c.time = time.Now() - - var data map[string]map[string]CounterValues + var data map[string]map[string]perftypes.CounterValues for _, counter := range c.counters { 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] if data == nil { - data = make(map[string]map[string]CounterValues, itemCount) + data = make(map[string]map[string]perftypes.CounterValues, itemCount) } var metricType prometheus.ValueType - if val, ok := supportedCounterTypes[counter.Type]; ok { + if val, ok := perftypes.SupportedCounterTypes[counter.Type]; ok { metricType = val } else { metricType = prometheus.GaugeValue @@ -184,15 +173,15 @@ func (c *Collector) Collect() (map[string]map[string]CounterValues, error) { continue } - if instanceName == "" { - instanceName = EmptyInstance + if instanceName == "" || instanceName == "*" { + instanceName = perftypes.EmptyInstance } 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, } @@ -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 switch counter.Type { - case PERF_ELAPSED_TIME: - values.FirstValue = float64(item.RawValue.FirstValue-WindowsEpoch) / counter.Frequency - values.SecondValue = float64(item.RawValue.SecondValue-WindowsEpoch) / counter.Frequency - case PERF_100NSEC_TIMER, PERF_PRECISION_100NS_TIMER: - values.FirstValue = float64(item.RawValue.FirstValue) * TicksToSecondScaleFactor - values.SecondValue = float64(item.RawValue.SecondValue) * TicksToSecondScaleFactor + case perftypes.PERF_ELAPSED_TIME: + values.FirstValue = float64(item.RawValue.FirstValue-perftypes.WindowsEpoch) / counter.Frequency + values.SecondValue = float64(item.RawValue.SecondValue-perftypes.WindowsEpoch) / counter.Frequency + case perftypes.PERF_100NSEC_TIMER, perftypes.PERF_PRECISION_100NS_TIMER: + values.FirstValue = float64(item.RawValue.FirstValue) * perftypes.TicksToSecondScaleFactor + values.SecondValue = float64(item.RawValue.SecondValue) * perftypes.TicksToSecondScaleFactor default: values.FirstValue = float64(item.RawValue.FirstValue) values.SecondValue = float64(item.RawValue.SecondValue) @@ -228,7 +217,7 @@ func (c *Collector) Close() { func formatCounterPath(object, instance, counterName string) string { var counterPath string - if instance == EmptyInstance { + if instance == perftypes.EmptyInstance { counterPath = fmt.Sprintf(`\%s\%s`, object, counterName) } else { counterPath = fmt.Sprintf(`\%s(%s)\%s`, object, instance, counterName) diff --git a/internal/perfdata/collector_bench_test.go b/internal/perfdata/v2/collector_bench_test.go similarity index 83% rename from internal/perfdata/collector_bench_test.go rename to internal/perfdata/v2/collector_bench_test.go index 381829d4..c62c4afe 100644 --- a/internal/perfdata/collector_bench_test.go +++ b/internal/perfdata/v2/collector_bench_test.go @@ -1,9 +1,9 @@ -package perfdata_test +package v2_test import ( "testing" - "github.com/prometheus-community/windows_exporter/internal/perfdata" + v2 "github.com/prometheus-community/windows_exporter/internal/perfdata/v2" "github.com/stretchr/testify/require" ) @@ -38,7 +38,7 @@ func BenchmarkTestCollector(b *testing.B) { "Working Set Peak", "Working Set", } - performanceData, err := perfdata.NewCollector("Process", []string{"*"}, counters) + performanceData, err := v2.NewCollector("Process", []string{"*"}, counters) require.NoError(b, err) for i := 0; i < b.N; i++ { diff --git a/internal/perfdata/collector_test.go b/internal/perfdata/v2/collector_test.go similarity index 90% rename from internal/perfdata/collector_test.go rename to internal/perfdata/v2/collector_test.go index e2ef0112..b37877e8 100644 --- a/internal/perfdata/collector_test.go +++ b/internal/perfdata/v2/collector_test.go @@ -1,12 +1,12 @@ //go:build windows -package perfdata_test +package v2_test import ( "testing" "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/require" ) @@ -61,7 +61,7 @@ func TestCollector(t *testing.T) { t.Run(tc.object, func(t *testing.T) { 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) time.Sleep(100 * time.Millisecond) diff --git a/internal/perfdata/error.go b/internal/perfdata/v2/error.go similarity index 96% rename from internal/perfdata/error.go rename to internal/perfdata/v2/error.go index acff5ebb..1eb351fb 100644 --- a/internal/perfdata/error.go +++ b/internal/perfdata/v2/error.go @@ -1,4 +1,4 @@ -package perfdata +package v2 import "errors" diff --git a/internal/perfdata/pdh.go b/internal/perfdata/v2/pdh.go similarity index 97% rename from internal/perfdata/pdh.go rename to internal/perfdata/v2/pdh.go index e2a90914..171b3703 100644 --- a/internal/perfdata/pdh.go +++ b/internal/perfdata/v2/pdh.go @@ -31,7 +31,7 @@ //go:build windows -package perfdata +package v2 import ( "fmt" @@ -44,10 +44,9 @@ import ( // Error codes. const ( - ErrorSuccess = 0 - ErrorFailure = 1 - ErrorInvalidFunction = 1 - EpochDifferenceMicros int64 = 11644473600000000 + ErrorSuccess = 0 + ErrorFailure = 1 + ErrorInvalidFunction = 1 ) type ( @@ -289,13 +288,13 @@ var ( // \\LogicalDisk(C:)\% Free Space // // 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 -// full implementation of the pdh.dll API, except with a GUI and all that. The registry setting also provides an +// 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 v1 setting also provides an // interface to the available counters, and can be found at the following key: // // 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 // 1847 @@ -325,12 +324,6 @@ func PdhAddCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData u 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 // Windows versions higher than Vista. func PdhAddEnglishCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData uintptr, phCounter *pdhCounterHandle) uint32 { diff --git a/internal/perfdata/pdh_amd64.go b/internal/perfdata/v2/pdh_amd64.go similarity index 99% rename from internal/perfdata/pdh_amd64.go rename to internal/perfdata/v2/pdh_amd64.go index 02ce5ec0..a107b02e 100644 --- a/internal/perfdata/pdh_amd64.go +++ b/internal/perfdata/v2/pdh_amd64.go @@ -31,7 +31,7 @@ //go:build windows -package perfdata +package v2 import "golang.org/x/sys/windows" diff --git a/internal/perfdata/pdh_arm64.go b/internal/perfdata/v2/pdh_arm64.go similarity index 99% rename from internal/perfdata/pdh_arm64.go rename to internal/perfdata/v2/pdh_arm64.go index 0047e6ac..1e20ff33 100644 --- a/internal/perfdata/pdh_arm64.go +++ b/internal/perfdata/v2/pdh_arm64.go @@ -31,7 +31,7 @@ //go:build windows -package perfdata +package v2 import "golang.org/x/sys/windows" diff --git a/internal/perflib/const.go b/internal/perflib/const.go deleted file mode 100644 index 12f1f219..00000000 --- a/internal/perflib/const.go +++ /dev/null @@ -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 -) diff --git a/internal/types/types.go b/internal/types/types.go index 8fd21d10..d18f11e7 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -1,9 +1,9 @@ package types import ( - "github.com/prometheus-community/windows_exporter/internal/perflib" + v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1" ) type ScrapeContext struct { - PerfObjects map[string]*perflib.PerfObject + PerfObjects map[string]*v1.PerfObject } diff --git a/pkg/collector/collector.go b/pkg/collector/collector.go index 1f0ed945..ba592892 100644 --- a/pkg/collector/collector.go +++ b/pkg/collector/collector.go @@ -8,6 +8,7 @@ import ( "log/slog" "slices" "strings" + "sync" "github.com/alecthomas/kingpin/v2" "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/vmware" "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/yusufpapurcu/wmi" ) @@ -159,7 +160,7 @@ func (c *MetricCollectors) SetPerfCounterQuery(logger *slog.Logger) error { perfIndicies = make([]string, 0, len(perfCounterNames)) for _, cn := range perfCounterNames { - perfIndicies = append(perfIndicies, perflib.MapCounterToIndex(cn)) + perfIndicies = append(perfIndicies, v1.MapCounterToIndex(cn)) } 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) } + 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 { - if err = collector.Build(logger, c.WMIClient); err != nil { - return fmt.Errorf("error build collector %s: %w", collector.GetName(), err) - } + go func() { + 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. @@ -204,7 +223,7 @@ func (c *MetricCollectors) PrepareScrapeContext() (*types.ScrapeContext, error) return &types.ScrapeContext{}, nil } - perfObjects, err := perflib.GetPerflibSnapshot(c.PerfCounterQuery) + perfObjects, err := v1.GetPerflibSnapshot(c.PerfCounterQuery) if err != nil { return nil, err }