mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-07 21:46:37 +00:00
performancecounter: Add the possibility to request formatted values (#1830)
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="all" type="GoApplicationRunConfiguration" factoryName="Go Application" folderName="run">
|
<configuration default="false" name="all" type="GoApplicationRunConfiguration" factoryName="Go Application" folderName="run">
|
||||||
<module name="windows_exporter" />
|
<module name="windows_exporter" />
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
<parameters value="--web.listen-address=127.0.0.1:9182 --log.level=info --collectors.enabled=ad,adcs,adfs,cache,container,cpu,cpu_info,cs,dfsr,dhcp,diskdrive,dns,exchange,filetime,fsrmquota,hyperv,iis,license,logical_disk,logon,memory,mscluster,msmq,mssql,net,netframework,nps,os,pagefile,performancecounter,physical_disk,printer,process,remote_fx,scheduled_task,service,smb,smbclient,smtp,system,tcp,terminal_services,thermalzone,time,udp,update,vmware,performancecounter --debug.enabled --collector.performancecounter.objects='[{ "name": "memory", "object": "Memory", "counters": [{ "name":"Cache Faults/sec", "type":"counter" }]}]'" />
|
<parameters value="--web.listen-address=127.0.0.1:9182 --log.level=info --collectors.enabled=ad,adcs,adfs,cache,container,cpu,cpu_info,cs,dfsr,dhcp,diskdrive,dns,exchange,filetime,fsrmquota,hyperv,iis,license,logical_disk,logon,memory,mscluster,msmq,mssql,net,netframework,nps,os,pagefile,performancecounter,physical_disk,printer,process,remote_fx,scheduled_task,service,smb,smbclient,smtp,system,tcp,terminal_services,thermalzone,time,udp,update,vmware,performancecounter --debug.enabled --collector.performancecounter.objects='[{ "name": "memory", "type": "formatted", "object": "Memory", "counters": [{ "name":"Cache Faults/sec", "type":"counter" }]}]'" />
|
||||||
<sudo value="true" />
|
<sudo value="true" />
|
||||||
<kind value="PACKAGE" />
|
<kind value="PACKAGE" />
|
||||||
<package value="github.com/prometheus-community/windows_exporter/cmd/windows_exporter" />
|
<package value="github.com/prometheus-community/windows_exporter/cmd/windows_exporter" />
|
||||||
|
|||||||
15
config.yaml
15
config.yaml
@@ -7,10 +7,17 @@ collector:
|
|||||||
include: "windows_exporter"
|
include: "windows_exporter"
|
||||||
performancecounter:
|
performancecounter:
|
||||||
objects: |-
|
objects: |-
|
||||||
- name: memory
|
- name: photon_udp
|
||||||
object: "Memory"
|
object: "Photon Socket Server: UDP"
|
||||||
|
instances: ["*"]
|
||||||
counters:
|
counters:
|
||||||
- name: "Cache Faults/sec"
|
- name: "UDP: Datagrams in"
|
||||||
type: "counter" # optional
|
metric: "photon_udp_datagrams"
|
||||||
|
labels:
|
||||||
|
direction: "in"
|
||||||
|
- name: "UDP: Datagrams out"
|
||||||
|
metric: "photon_udp_datagrams"
|
||||||
|
labels:
|
||||||
|
direction: "out"
|
||||||
log:
|
log:
|
||||||
level: warn
|
level: warn
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ YAML:
|
|||||||
state: idle
|
state: idle
|
||||||
- name: memory
|
- name: memory
|
||||||
object: "Memory"
|
object: "Memory"
|
||||||
|
type: "formatted"
|
||||||
counters:
|
counters:
|
||||||
- name: "Cache Faults/sec"
|
- name: "Cache Faults/sec"
|
||||||
type: "counter" # optional
|
type: "counter" # optional
|
||||||
@@ -98,6 +99,7 @@ YAML:
|
|||||||
{
|
{
|
||||||
"name": "memory",
|
"name": "memory",
|
||||||
"object": "Memory",
|
"object": "Memory",
|
||||||
|
"type": "formatted",
|
||||||
"counters": [
|
"counters": [
|
||||||
{
|
{
|
||||||
"name": "Cache Faults/sec",
|
"name": "Cache Faults/sec",
|
||||||
@@ -120,6 +122,33 @@ ObjectName is the Object to query for, like Processor, DirectoryServices, Logica
|
|||||||
|
|
||||||
The collector supports only english named counter. Localized counter-names are not supported.
|
The collector supports only english named counter. Localized counter-names are not supported.
|
||||||
|
|
||||||
|
#### type
|
||||||
|
|
||||||
|
The counter-type. The value can be `raw` or `formatted`. Optional and defaults to `raw`.
|
||||||
|
|
||||||
|
- `raw` returns the raw value of the counter. This is the default.
|
||||||
|
- `formatted` returns the formatted value of the counter. This is useful for counters like `Processor Information` where the value is a percentage.
|
||||||
|
|
||||||
|
The difference between a raw Windows Performance Counter and a formatted Windows Performance Counter is about how the data is presented and processed:
|
||||||
|
|
||||||
|
1. Raw Windows Performance Counter:
|
||||||
|
|
||||||
|
This provides the counter's data in its basic, unprocessed form.
|
||||||
|
The values may represent cumulative counts, time intervals, or other uncalibrated metrics.
|
||||||
|
Interpreting these values often requires more calculations or context, such as calculating deltas or normalizing values over time.
|
||||||
|
|
||||||
|
2. Formatted Windows Performance Counter:
|
||||||
|
|
||||||
|
This presents data that has already been processed and interpreted according to the counter type (e.g., rates per second, averages, percentages).
|
||||||
|
Formatted counters are easier to understand directly since the necessary calculations have been applied.
|
||||||
|
These are often what monitoring tools display to users because they are meaningful at a glance.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
* A raw counter for CPU time might give the total number of clock ticks used since the system started.
|
||||||
|
* A formatted counter would convert this into a percentage of CPU utilization over a specific time interval.
|
||||||
|
|
||||||
|
|
||||||
#### instances
|
#### instances
|
||||||
|
|
||||||
The instances key (this is an array) declares the instances of a counter you would like returned, it can be one or more values.
|
The instances key (this is an array) declares the instances of a counter you would like returned, it can be one or more values.
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("DirectoryServices", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DirectoryServices", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create DirectoryServices collector: %w", err)
|
return fmt.Errorf("failed to create DirectoryServices collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Certification Authority", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Certification Authority", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Certification Authority collector: %w", err)
|
return fmt.Errorf("failed to create Certification Authority collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("AD FS", nil)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "AD FS", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create AD FS collector: %w", err)
|
return fmt.Errorf("failed to create AD FS collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
2
internal/collector/cache/cache.go
vendored
2
internal/collector/cache/cache.go
vendored
@@ -100,7 +100,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Cache", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Cache", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Cache collector: %w", err)
|
return fmt.Errorf("failed to create Cache collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
|
|
||||||
c.mu = sync.Mutex{}
|
c.mu = sync.Mutex{}
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Processor Information", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Processor Information", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Processor Information collector: %w", err)
|
return fmt.Errorf("failed to create Processor Information collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,21 +163,21 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
if slices.Contains(c.config.CollectorsEnabled, "connection") {
|
if slices.Contains(c.config.CollectorsEnabled, "connection") {
|
||||||
c.perfDataCollectorConnection, err = pdh.NewCollector[perfDataCounterValuesConnection]("DFS Replication Connections", pdh.InstancesAll)
|
c.perfDataCollectorConnection, err = pdh.NewCollector[perfDataCounterValuesConnection](pdh.CounterTypeRaw, "DFS Replication Connections", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create DFS Replication Connections collector: %w", err)
|
return fmt.Errorf("failed to create DFS Replication Connections collector: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if slices.Contains(c.config.CollectorsEnabled, "folder") {
|
if slices.Contains(c.config.CollectorsEnabled, "folder") {
|
||||||
c.perfDataCollectorFolder, err = pdh.NewCollector[perfDataCounterValuesFolder]("DFS Replicated Folders", pdh.InstancesAll)
|
c.perfDataCollectorFolder, err = pdh.NewCollector[perfDataCounterValuesFolder](pdh.CounterTypeRaw, "DFS Replicated Folders", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create DFS Replicated Folders collector: %w", err)
|
return fmt.Errorf("failed to create DFS Replicated Folders collector: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if slices.Contains(c.config.CollectorsEnabled, "volume") {
|
if slices.Contains(c.config.CollectorsEnabled, "volume") {
|
||||||
c.perfDataCollectorVolume, err = pdh.NewCollector[perfDataCounterValuesVolume]("DFS Replication Service Volumes", pdh.InstancesAll)
|
c.perfDataCollectorVolume, err = pdh.NewCollector[perfDataCounterValuesVolume](pdh.CounterTypeRaw, "DFS Replication Service Volumes", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create DFS Replication Service Volumes collector: %w", err)
|
return fmt.Errorf("failed to create DFS Replication Service Volumes collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("DHCP Server", nil)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DHCP Server", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create DHCP Server collector: %w", err)
|
return fmt.Errorf("failed to create DHCP Server collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("DNS", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DNS", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create DNS collector: %w", err)
|
return fmt.Errorf("failed to create DNS collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ type perfDataCounterValuesActiveSync struct {
|
|||||||
func (c *Collector) buildActiveSync() error {
|
func (c *Collector) buildActiveSync() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorActiveSync, err = pdh.NewCollector[perfDataCounterValuesActiveSync]("MSExchange ActiveSync", pdh.InstancesAll)
|
c.perfDataCollectorActiveSync, err = pdh.NewCollector[perfDataCounterValuesActiveSync](pdh.CounterTypeRaw, "MSExchange ActiveSync", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange ActiveSync collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange ActiveSync collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ type perfDataCounterValuesADAccessProcesses struct {
|
|||||||
func (c *Collector) buildADAccessProcesses() error {
|
func (c *Collector) buildADAccessProcesses() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorADAccessProcesses, err = pdh.NewCollector[perfDataCounterValuesADAccessProcesses]("MSExchange ADAccess Processes", pdh.InstancesAll)
|
c.perfDataCollectorADAccessProcesses, err = pdh.NewCollector[perfDataCounterValuesADAccessProcesses](pdh.CounterTypeRaw, "MSExchange ADAccess Processes", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange ADAccess Processes collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange ADAccess Processes collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type perfDataCounterValuesAutoDiscover struct {
|
|||||||
func (c *Collector) buildAutoDiscover() error {
|
func (c *Collector) buildAutoDiscover() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorAutoDiscover, err = pdh.NewCollector[perfDataCounterValuesAutoDiscover]("MSExchange Autodiscover", pdh.InstancesAll)
|
c.perfDataCollectorAutoDiscover, err = pdh.NewCollector[perfDataCounterValuesAutoDiscover](pdh.CounterTypeRaw, "MSExchange Autodiscover", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type perfDataCounterValuesAvailabilityService struct {
|
|||||||
func (c *Collector) buildAvailabilityService() error {
|
func (c *Collector) buildAvailabilityService() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorAvailabilityService, err = pdh.NewCollector[perfDataCounterValuesAvailabilityService]("MSExchange Availability Service", pdh.InstancesAll)
|
c.perfDataCollectorAvailabilityService, err = pdh.NewCollector[perfDataCounterValuesAvailabilityService](pdh.CounterTypeRaw, "MSExchange Availability Service", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange Availability Service collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange Availability Service collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ type perfDataCounterValuesHTTPProxy struct {
|
|||||||
func (c *Collector) buildHTTPProxy() error {
|
func (c *Collector) buildHTTPProxy() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorHTTPProxy, err = pdh.NewCollector[perfDataCounterValuesHTTPProxy]("MSExchange HttpProxy", pdh.InstancesAll)
|
c.perfDataCollectorHTTPProxy, err = pdh.NewCollector[perfDataCounterValuesHTTPProxy](pdh.CounterTypeRaw, "MSExchange HttpProxy", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange HttpProxy collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange HttpProxy collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type perfDataCounterValuesMapiHttpEmsmdb struct {
|
|||||||
func (c *Collector) buildMapiHttpEmsmdb() error {
|
func (c *Collector) buildMapiHttpEmsmdb() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorMapiHttpEmsmdb, err = pdh.NewCollector[perfDataCounterValuesMapiHttpEmsmdb]("MSExchange MapiHttp Emsmdb", pdh.InstancesAll)
|
c.perfDataCollectorMapiHttpEmsmdb, err = pdh.NewCollector[perfDataCounterValuesMapiHttpEmsmdb](pdh.CounterTypeRaw, "MSExchange MapiHttp Emsmdb", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange MapiHttp Emsmdb: %w", err)
|
return fmt.Errorf("failed to create MSExchange MapiHttp Emsmdb: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type perfDataCounterValuesOWA struct {
|
|||||||
func (c *Collector) buildOWA() error {
|
func (c *Collector) buildOWA() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorOWA, err = pdh.NewCollector[perfDataCounterValuesOWA]("MSExchange OWA", pdh.InstancesAll)
|
c.perfDataCollectorOWA, err = pdh.NewCollector[perfDataCounterValuesOWA](pdh.CounterTypeRaw, "MSExchange OWA", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange OWA collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange OWA collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ type perfDataCounterValuesRpcClientAccess struct {
|
|||||||
func (c *Collector) buildRpcClientAccess() error {
|
func (c *Collector) buildRpcClientAccess() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorRpcClientAccess, err = pdh.NewCollector[perfDataCounterValuesRpcClientAccess]("MSExchange RpcClientAccess", pdh.InstancesAll)
|
c.perfDataCollectorRpcClientAccess, err = pdh.NewCollector[perfDataCounterValuesRpcClientAccess](pdh.CounterTypeRaw, "MSExchange RpcClientAccess", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange RpcClientAccess collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange RpcClientAccess collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ type perfDataCounterValuesTransportQueues struct {
|
|||||||
func (c *Collector) buildTransportQueues() error {
|
func (c *Collector) buildTransportQueues() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorTransportQueues, err = pdh.NewCollector[perfDataCounterValuesTransportQueues]("MSExchangeTransport Queues", pdh.InstancesAll)
|
c.perfDataCollectorTransportQueues, err = pdh.NewCollector[perfDataCounterValuesTransportQueues](pdh.CounterTypeRaw, "MSExchangeTransport Queues", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchangeTransport Queues collector: %w", err)
|
return fmt.Errorf("failed to create MSExchangeTransport Queues collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ type perfDataCounterValuesWorkloadManagementWorkloads struct {
|
|||||||
func (c *Collector) buildWorkloadManagementWorkloads() error {
|
func (c *Collector) buildWorkloadManagementWorkloads() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorWorkloadManagementWorkloads, err = pdh.NewCollector[perfDataCounterValuesWorkloadManagementWorkloads]("MSExchange WorkloadManagement Workloads", pdh.InstancesAll)
|
c.perfDataCollectorWorkloadManagementWorkloads, err = pdh.NewCollector[perfDataCounterValuesWorkloadManagementWorkloads](pdh.CounterTypeRaw, "MSExchange WorkloadManagement Workloads", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSExchange WorkloadManagement Workloads collector: %w", err)
|
return fmt.Errorf("failed to create MSExchange WorkloadManagement Workloads collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ type perfDataCounterValuesDataStore struct {
|
|||||||
func (c *Collector) buildDataStore() error {
|
func (c *Collector) buildDataStore() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorDataStore, err = pdh.NewCollector[perfDataCounterValuesDataStore]("Hyper-V DataStore", pdh.InstancesAll)
|
c.perfDataCollectorDataStore, err = pdh.NewCollector[perfDataCounterValuesDataStore](pdh.CounterTypeRaw, "Hyper-V DataStore", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V DataStore collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V DataStore collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (c *Collector) buildDynamicMemoryBalancer() error {
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
// https://learn.microsoft.com/en-us/archive/blogs/chrisavis/monitoring-dynamic-memory-in-windows-server-hyper-v-2012
|
// https://learn.microsoft.com/en-us/archive/blogs/chrisavis/monitoring-dynamic-memory-in-windows-server-hyper-v-2012
|
||||||
c.perfDataCollectorDynamicMemoryBalancer, err = pdh.NewCollector[perfDataCounterValuesDynamicMemoryBalancer]("Hyper-V Dynamic Memory Balancer", pdh.InstancesAll)
|
c.perfDataCollectorDynamicMemoryBalancer, err = pdh.NewCollector[perfDataCounterValuesDynamicMemoryBalancer](pdh.CounterTypeRaw, "Hyper-V Dynamic Memory Balancer", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ type perfDataCounterValuesDynamicMemoryVM struct {
|
|||||||
func (c *Collector) buildDynamicMemoryVM() error {
|
func (c *Collector) buildDynamicMemoryVM() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorDynamicMemoryVM, err = pdh.NewCollector[perfDataCounterValuesDynamicMemoryVM]("Hyper-V Dynamic Memory VM", pdh.InstancesAll)
|
c.perfDataCollectorDynamicMemoryVM, err = pdh.NewCollector[perfDataCounterValuesDynamicMemoryVM](pdh.CounterTypeRaw, "Hyper-V Dynamic Memory VM", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Dynamic Memory VM collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Dynamic Memory VM collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ type perfDataCounterValuesHypervisorLogicalProcessor struct {
|
|||||||
func (c *Collector) buildHypervisorLogicalProcessor() error {
|
func (c *Collector) buildHypervisorLogicalProcessor() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorHypervisorLogicalProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorLogicalProcessor]("Hyper-V Hypervisor Logical Processor", pdh.InstancesAll)
|
c.perfDataCollectorHypervisorLogicalProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorLogicalProcessor](pdh.CounterTypeRaw, "Hyper-V Hypervisor Logical Processor", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Hypervisor Logical Processor collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Hypervisor Logical Processor collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ type perfDataCounterValuesHypervisorRootPartition struct {
|
|||||||
func (c *Collector) buildHypervisorRootPartition() error {
|
func (c *Collector) buildHypervisorRootPartition() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorHypervisorRootPartition, err = pdh.NewCollector[perfDataCounterValuesHypervisorRootPartition]("Hyper-V Hypervisor Root Partition", []string{"Root"})
|
c.perfDataCollectorHypervisorRootPartition, err = pdh.NewCollector[perfDataCounterValuesHypervisorRootPartition](pdh.CounterTypeRaw, "Hyper-V Hypervisor Root Partition", []string{"Root"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Hypervisor Root Partition collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Hypervisor Root Partition collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ type perfDataCounterValuesHypervisorRootVirtualProcessor struct {
|
|||||||
func (c *Collector) buildHypervisorRootVirtualProcessor() error {
|
func (c *Collector) buildHypervisorRootVirtualProcessor() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorHypervisorRootVirtualProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorRootVirtualProcessor]("Hyper-V Hypervisor Root Virtual Processor", pdh.InstancesAll)
|
c.perfDataCollectorHypervisorRootVirtualProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorRootVirtualProcessor](pdh.CounterTypeRaw, "Hyper-V Hypervisor Root Virtual Processor", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Hypervisor Root Virtual Processor collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Hypervisor Root Virtual Processor collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ type perfDataCounterValuesHypervisorVirtualProcessor struct {
|
|||||||
func (c *Collector) buildHypervisorVirtualProcessor() error {
|
func (c *Collector) buildHypervisorVirtualProcessor() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorHypervisorVirtualProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorVirtualProcessor]("Hyper-V Hypervisor Virtual Processor", pdh.InstancesAll)
|
c.perfDataCollectorHypervisorVirtualProcessor, err = pdh.NewCollector[perfDataCounterValuesHypervisorVirtualProcessor](pdh.CounterTypeRaw, "Hyper-V Hypervisor Virtual Processor", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Hypervisor Virtual Processor collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Hypervisor Virtual Processor collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ type perfDataCounterValuesLegacyNetworkAdapter struct {
|
|||||||
func (c *Collector) buildLegacyNetworkAdapter() error {
|
func (c *Collector) buildLegacyNetworkAdapter() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorLegacyNetworkAdapter, err = pdh.NewCollector[perfDataCounterValuesLegacyNetworkAdapter]("Hyper-V Legacy Network Adapter", pdh.InstancesAll)
|
c.perfDataCollectorLegacyNetworkAdapter, err = pdh.NewCollector[perfDataCounterValuesLegacyNetworkAdapter](pdh.CounterTypeRaw, "Hyper-V Legacy Network Adapter", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Legacy Network Adapter collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Legacy Network Adapter collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ type perfDataCounterValuesVirtualMachineHealthSummary struct {
|
|||||||
func (c *Collector) buildVirtualMachineHealthSummary() error {
|
func (c *Collector) buildVirtualMachineHealthSummary() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorVirtualMachineHealthSummary, err = pdh.NewCollector[perfDataCounterValuesVirtualMachineHealthSummary]("Hyper-V Virtual Machine Health Summary", nil)
|
c.perfDataCollectorVirtualMachineHealthSummary, err = pdh.NewCollector[perfDataCounterValuesVirtualMachineHealthSummary](pdh.CounterTypeRaw, "Hyper-V Virtual Machine Health Summary", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Virtual Machine Health Summary collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ type perfDataCounterValuesVirtualMachineVidPartition struct {
|
|||||||
func (c *Collector) buildVirtualMachineVidPartition() error {
|
func (c *Collector) buildVirtualMachineVidPartition() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorVirtualMachineVidPartition, err = pdh.NewCollector[perfDataCounterValuesVirtualMachineVidPartition]("Hyper-V VM Vid Partition", pdh.InstancesAll)
|
c.perfDataCollectorVirtualMachineVidPartition, err = pdh.NewCollector[perfDataCounterValuesVirtualMachineVidPartition](pdh.CounterTypeRaw, "Hyper-V VM Vid Partition", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V VM Vid Partition collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V VM Vid Partition collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ type perfDataCounterValuesVirtualNetworkAdapter struct {
|
|||||||
func (c *Collector) buildVirtualNetworkAdapter() error {
|
func (c *Collector) buildVirtualNetworkAdapter() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorVirtualNetworkAdapter, err = pdh.NewCollector[perfDataCounterValuesVirtualNetworkAdapter]("Hyper-V Virtual Network Adapter", pdh.InstancesAll)
|
c.perfDataCollectorVirtualNetworkAdapter, err = pdh.NewCollector[perfDataCounterValuesVirtualNetworkAdapter](pdh.CounterTypeRaw, "Hyper-V Virtual Network Adapter", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Virtual Network Adapter collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Virtual Network Adapter collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ type perfDataCounterValuesVirtualNetworkAdapterDropReasons struct {
|
|||||||
func (c *Collector) buildVirtualNetworkAdapterDropReasons() error {
|
func (c *Collector) buildVirtualNetworkAdapterDropReasons() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorVirtualNetworkAdapterDropReasons, err = pdh.NewCollector[perfDataCounterValuesVirtualNetworkAdapterDropReasons]("Hyper-V Virtual Network Adapter Drop Reasons", pdh.InstancesAll)
|
c.perfDataCollectorVirtualNetworkAdapterDropReasons, err = pdh.NewCollector[perfDataCounterValuesVirtualNetworkAdapterDropReasons](pdh.CounterTypeRaw, "Hyper-V Virtual Network Adapter Drop Reasons", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Virtual Network Adapter Drop Reasons collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Virtual Network Adapter Drop Reasons collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ type perfDataCounterValuesVirtualSMB struct {
|
|||||||
func (c *Collector) buildVirtualSMB() error {
|
func (c *Collector) buildVirtualSMB() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorVirtualSMB, err = pdh.NewCollector[perfDataCounterValuesVirtualSMB]("Hyper-V Virtual SMB", pdh.InstancesAll)
|
c.perfDataCollectorVirtualSMB, err = pdh.NewCollector[perfDataCounterValuesVirtualSMB](pdh.CounterTypeRaw, "Hyper-V Virtual SMB", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Virtual SMB collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Virtual SMB collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ type perfDataCounterValuesVirtualStorageDevice struct {
|
|||||||
func (c *Collector) buildVirtualStorageDevice() error {
|
func (c *Collector) buildVirtualStorageDevice() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorVirtualStorageDevice, err = pdh.NewCollector[perfDataCounterValuesVirtualStorageDevice]("Hyper-V Virtual Storage Device", pdh.InstancesAll)
|
c.perfDataCollectorVirtualStorageDevice, err = pdh.NewCollector[perfDataCounterValuesVirtualStorageDevice](pdh.CounterTypeRaw, "Hyper-V Virtual Storage Device", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Virtual Storage Device collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Virtual Storage Device collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ type perfDataCounterValuesVirtualSwitch struct {
|
|||||||
func (c *Collector) buildVirtualSwitch() error {
|
func (c *Collector) buildVirtualSwitch() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorVirtualSwitch, err = pdh.NewCollector[perfDataCounterValuesVirtualSwitch]("Hyper-V Virtual Switch", pdh.InstancesAll)
|
c.perfDataCollectorVirtualSwitch, err = pdh.NewCollector[perfDataCounterValuesVirtualSwitch](pdh.CounterTypeRaw, "Hyper-V Virtual Switch", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Hyper-V Virtual Switch collector: %w", err)
|
return fmt.Errorf("failed to create Hyper-V Virtual Switch collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ var applicationStates = map[uint32]string{
|
|||||||
func (c *Collector) buildAppPoolWAS() error {
|
func (c *Collector) buildAppPoolWAS() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorAppPoolWAS, err = pdh.NewCollector[perfDataCounterValuesAppPoolWAS]("APP_POOL_WAS", pdh.InstancesAll)
|
c.perfDataCollectorAppPoolWAS, err = pdh.NewCollector[perfDataCounterValuesAppPoolWAS](pdh.CounterTypeRaw, "APP_POOL_WAS", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create APP_POOL_WAS collector: %w", err)
|
return fmt.Errorf("failed to create APP_POOL_WAS collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,13 +150,13 @@ func (p perfDataCounterValuesW3SVCW3WPV8) GetName() string {
|
|||||||
func (c *Collector) buildW3SVCW3WP() error {
|
func (c *Collector) buildW3SVCW3WP() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.w3SVCW3WPPerfDataCollector, err = pdh.NewCollector[perfDataCounterValuesW3SVCW3WP]("W3SVC_W3WP", pdh.InstancesAll)
|
c.w3SVCW3WPPerfDataCollector, err = pdh.NewCollector[perfDataCounterValuesW3SVCW3WP](pdh.CounterTypeRaw, "W3SVC_W3WP", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create W3SVC_W3WP collector: %w", err)
|
return fmt.Errorf("failed to create W3SVC_W3WP collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.iisVersion.major >= 8 {
|
if c.iisVersion.major >= 8 {
|
||||||
c.w3SVCW3WPPerfDataCollectorV8, err = pdh.NewCollector[perfDataCounterValuesW3SVCW3WPV8]("W3SVC_W3WP", pdh.InstancesAll)
|
c.w3SVCW3WPPerfDataCollectorV8, err = pdh.NewCollector[perfDataCounterValuesW3SVCW3WPV8](pdh.CounterTypeRaw, "W3SVC_W3WP", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create W3SVC_W3WP collector: %w", err)
|
return fmt.Errorf("failed to create W3SVC_W3WP collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ func (p perfDataCounterValuesWebService) GetName() string {
|
|||||||
func (c *Collector) buildWebService() error {
|
func (c *Collector) buildWebService() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorWebService, err = pdh.NewCollector[perfDataCounterValuesWebService]("Web Service", pdh.InstancesAll)
|
c.perfDataCollectorWebService, err = pdh.NewCollector[perfDataCounterValuesWebService](pdh.CounterTypeRaw, "Web Service", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Web Service collector: %w", err)
|
return fmt.Errorf("failed to create Web Service collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func (p perfDataCounterServiceCache) GetName() string {
|
|||||||
func (c *Collector) buildWebServiceCache() error {
|
func (c *Collector) buildWebServiceCache() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.serviceCachePerfDataCollector, err = pdh.NewCollector[perfDataCounterServiceCache]("Web Service Cache", pdh.InstancesAll)
|
c.serviceCachePerfDataCollector, err = pdh.NewCollector[perfDataCounterServiceCache](pdh.CounterTypeRaw, "Web Service Cache", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Web Service Cache collector: %w", err)
|
return fmt.Errorf("failed to create Web Service Cache collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("LogicalDisk", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "LogicalDisk", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create LogicalDisk collector: %w", err)
|
return fmt.Errorf("failed to create LogicalDisk collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Memory", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Memory", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Memory collector: %w", err)
|
return fmt.Errorf("failed to create Memory collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("MSMQ Queue", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "MSMQ Queue", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create MSMQ Queue collector: %w", err)
|
return fmt.Errorf("failed to create MSMQ Queue collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,9 +128,7 @@ func (c *Collector) buildAccessMethods() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.accessMethodsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesAccessMethods](
|
c.accessMethodsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesAccessMethods](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Access Methods"), nil)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Access Methods"), nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create AccessMethods collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create AccessMethods collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,9 +61,7 @@ func (c *Collector) buildAvailabilityReplica() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.availabilityReplicaPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesAvailabilityReplica](
|
c.availabilityReplicaPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesAvailabilityReplica](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Availability Replica"), pdh.InstancesAll)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Availability Replica"), pdh.InstancesAll,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Availability Replica collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Availability Replica collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,9 +86,7 @@ func (c *Collector) buildBufferManager() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.bufManPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesBufMan](
|
c.bufManPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesBufMan](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Buffer Manager"), nil)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Buffer Manager"), nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Buffer Manager collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Buffer Manager collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,13 +146,13 @@ func (c *Collector) buildDatabases() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.databasesPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesDatabases](c.mssqlGetPerfObjectName(sqlInstance.name, "Databases"), pdh.InstancesAll)
|
c.databasesPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesDatabases](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Databases"), pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Databases collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Databases collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if sqlInstance.isVersionGreaterOrEqualThan(serverVersion2019) {
|
if sqlInstance.isVersionGreaterOrEqualThan(serverVersion2019) {
|
||||||
c.databasesPerfDataCollectors2019[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesDatabases2019](c.mssqlGetPerfObjectName(sqlInstance.name, "Databases"), pdh.InstancesAll)
|
c.databasesPerfDataCollectors2019[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesDatabases2019](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Databases"), pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Databases 2019 collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Databases 2019 collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,9 +90,7 @@ func (c *Collector) buildDatabaseReplica() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.dbReplicaPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesDBReplica](
|
c.dbReplicaPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesDBReplica](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Database Replica"), pdh.InstancesAll)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Database Replica"), pdh.InstancesAll,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Database Replica collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Database Replica collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,9 +88,7 @@ func (c *Collector) buildGeneralStatistics() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.genStatsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesGenStats](
|
c.genStatsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesGenStats](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "General Statistics"), nil)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "General Statistics"), nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create General Statistics collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create General Statistics collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,7 @@ func (c *Collector) buildLocks() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.locksPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesLocks](
|
c.locksPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesLocks](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Locks"), pdh.InstancesAll)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Locks"), pdh.InstancesAll,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Locks collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Locks collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,9 +80,7 @@ func (c *Collector) buildMemoryManager() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.memMgrPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesMemMgr](
|
c.memMgrPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesMemMgr](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Memory Manager"), pdh.InstancesAll)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Memory Manager"), pdh.InstancesAll,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Memory Manager collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Memory Manager collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ func (c *Collector) buildSQLErrors() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.sqlErrorsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesSqlErrors](
|
c.sqlErrorsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesSqlErrors](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "SQL Errors"), pdh.InstancesAll)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "SQL Errors"), pdh.InstancesAll,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create SQL Errors collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create SQL Errors collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,7 @@ func (c *Collector) buildSQLStats() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.sqlStatsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesSqlStats](
|
c.sqlStatsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesSqlStats](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "SQL Statistics"), nil)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "SQL Statistics"), nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create SQL Statistics collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create SQL Statistics collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ func (c *Collector) buildTransactions() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.transactionsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesTransactions](
|
c.transactionsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesTransactions](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Transactions"), nil)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Transactions"), nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Transactions collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Transactions collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ func (c *Collector) buildWaitStats() error {
|
|||||||
errs := make([]error, 0, len(c.mssqlInstances))
|
errs := make([]error, 0, len(c.mssqlInstances))
|
||||||
|
|
||||||
for _, sqlInstance := range c.mssqlInstances {
|
for _, sqlInstance := range c.mssqlInstances {
|
||||||
c.waitStatsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesWaitStats](
|
c.waitStatsPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesWaitStats](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Wait Statistics"), pdh.InstancesAll)
|
||||||
c.mssqlGetPerfObjectName(sqlInstance.name, "Wait Statistics"), pdh.InstancesAll,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create Wait Statistics collector for instance %s: %w", sqlInstance.name, err))
|
errs = append(errs, fmt.Errorf("failed to create Wait Statistics collector for instance %s: %w", sqlInstance.name, err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Network Interface", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Network Interface", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Network Interface collector: %w", err)
|
return fmt.Errorf("failed to create Network Interface collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,12 +98,12 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
|
|
||||||
errs := make([]error, 0, 2)
|
errs := make([]error, 0, 2)
|
||||||
|
|
||||||
c.accessPerfDataCollector, err = pdh.NewCollector[perfDataCounterValuesAccess]("NPS Authentication Server", nil)
|
c.accessPerfDataCollector, err = pdh.NewCollector[perfDataCounterValuesAccess](pdh.CounterTypeRaw, "NPS Authentication Server", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create NPS Authentication Server collector: %w", err))
|
errs = append(errs, fmt.Errorf("failed to create NPS Authentication Server collector: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
c.accountingPerfDataCollector, err = pdh.NewCollector[perfDataCounterValuesAccounting]("NPS Accounting Server", nil)
|
c.accountingPerfDataCollector, err = pdh.NewCollector[perfDataCounterValuesAccounting](pdh.CounterTypeRaw, "NPS Accounting Server", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create NPS Accounting Server collector: %w", err))
|
errs = append(errs, fmt.Errorf("failed to create NPS Accounting Server collector: %w", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Paging File", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Paging File", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Paging File collector: %w", err)
|
return fmt.Errorf("failed to create Paging File collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,16 @@ import (
|
|||||||
|
|
||||||
const Name = "performancecounter"
|
const Name = "performancecounter"
|
||||||
|
|
||||||
var reNonAlphaNum = regexp.MustCompile(`[^a-zA-Z0-9]`)
|
var (
|
||||||
|
reNonAlphaNum = regexp.MustCompile(`[^a-zA-Z0-9]`)
|
||||||
|
|
||||||
|
//nolint:gochecknoglobals // strings.NewReplacer is safe for concurrent use
|
||||||
|
stringReplacer = strings.NewReplacer(
|
||||||
|
"%", "percent",
|
||||||
|
"(", "",
|
||||||
|
")", "",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Objects []Object `yaml:"objects"`
|
Objects []Object `yaml:"objects"`
|
||||||
@@ -200,7 +209,11 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||||||
|
|
||||||
valueType := reflect.StructOf(fields)
|
valueType := reflect.StructOf(fields)
|
||||||
|
|
||||||
collector, err := pdh.NewCollectorWithReflection(object.Object, object.Instances, valueType)
|
if object.Type == "" {
|
||||||
|
object.Type = pdh.CounterTypeRaw
|
||||||
|
}
|
||||||
|
|
||||||
|
collector, err := pdh.NewCollectorWithReflection(object.Type, object.Object, object.Instances, valueType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed collector for %s: %w", object.Name, err))
|
errs = append(errs, fmt.Errorf("failed collector for %s: %w", object.Name, err))
|
||||||
}
|
}
|
||||||
@@ -364,5 +377,5 @@ func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Ob
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sanitizeMetricName(name string) string {
|
func sanitizeMetricName(name string) string {
|
||||||
return strings.Trim(reNonAlphaNum.ReplaceAllString(strings.ToLower(name), "_"), "_")
|
return strings.Trim(reNonAlphaNum.ReplaceAllString(strings.ToLower(stringReplacer.Replace(name)), "_"), "_")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ func TestCollector(t *testing.T) {
|
|||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
object string
|
object string
|
||||||
|
counterType pdh.CounterType
|
||||||
instances []string
|
instances []string
|
||||||
instanceLabel string
|
instanceLabel string
|
||||||
buildErr string
|
buildErr string
|
||||||
@@ -59,11 +60,12 @@ func TestCollector(t *testing.T) {
|
|||||||
expectedMetrics *regexp.Regexp
|
expectedMetrics *regexp.Regexp
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "memory",
|
name: "memory",
|
||||||
object: "Memory",
|
object: "Memory",
|
||||||
instances: nil,
|
counterType: pdh.CounterTypeRaw,
|
||||||
buildErr: "",
|
instances: nil,
|
||||||
counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}},
|
buildErr: "",
|
||||||
|
counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}},
|
||||||
expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection.
|
expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection.
|
||||||
# TYPE windows_performancecounter_collector_duration_seconds gauge
|
# TYPE windows_performancecounter_collector_duration_seconds gauge
|
||||||
windows_performancecounter_collector_duration_seconds\{collector="memory"} [0-9.e+-]+
|
windows_performancecounter_collector_duration_seconds\{collector="memory"} [0-9.e+-]+
|
||||||
@@ -75,11 +77,12 @@ windows_performancecounter_collector_success\{collector="memory"} 1
|
|||||||
windows_performancecounter_memory_available_bytes [0-9.e+-]+`),
|
windows_performancecounter_memory_available_bytes [0-9.e+-]+`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "process",
|
name: "process",
|
||||||
object: "Process",
|
object: "Process",
|
||||||
instances: []string{"*"},
|
counterType: "",
|
||||||
buildErr: "",
|
instances: []string{"*"},
|
||||||
counters: []performancecounter.Counter{{Name: "Thread Count", Type: "counter"}},
|
buildErr: "",
|
||||||
|
counters: []performancecounter.Counter{{Name: "Thread Count", Type: "counter"}},
|
||||||
expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection.
|
expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection.
|
||||||
# TYPE windows_performancecounter_collector_duration_seconds gauge
|
# TYPE windows_performancecounter_collector_duration_seconds gauge
|
||||||
windows_performancecounter_collector_duration_seconds\{collector="process"} [0-9.e+-]+
|
windows_performancecounter_collector_duration_seconds\{collector="process"} [0-9.e+-]+
|
||||||
@@ -94,6 +97,7 @@ windows_performancecounter_process_thread_count\{instance=".+"} [0-9.e+-]+
|
|||||||
{
|
{
|
||||||
name: "processor_information",
|
name: "processor_information",
|
||||||
object: "Processor Information",
|
object: "Processor Information",
|
||||||
|
counterType: pdh.CounterTypeRaw,
|
||||||
instances: []string{"*"},
|
instances: []string{"*"},
|
||||||
instanceLabel: "core",
|
instanceLabel: "core",
|
||||||
buildErr: "",
|
buildErr: "",
|
||||||
@@ -108,11 +112,32 @@ windows_performancecounter_collector_success\{collector="processor_information"}
|
|||||||
# TYPE windows_performancecounter_processor_information_processor_time counter
|
# TYPE windows_performancecounter_processor_information_processor_time counter
|
||||||
windows_performancecounter_processor_information_processor_time\{core="0,0",state="active"} [0-9.e+-]+
|
windows_performancecounter_processor_information_processor_time\{core="0,0",state="active"} [0-9.e+-]+
|
||||||
windows_performancecounter_processor_information_processor_time\{core="0,0",state="idle"} [0-9.e+-]+
|
windows_performancecounter_processor_information_processor_time\{core="0,0",state="idle"} [0-9.e+-]+
|
||||||
|
.*`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "processor_information_formatted",
|
||||||
|
object: "Processor Information",
|
||||||
|
counterType: pdh.CounterTypeFormatted,
|
||||||
|
instances: []string{"*"},
|
||||||
|
instanceLabel: "core",
|
||||||
|
buildErr: "",
|
||||||
|
counters: []performancecounter.Counter{{Name: "% Processor Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "active"}}, {Name: "% Idle Time", Metric: "windows_performancecounter_processor_information_processor_time", Labels: map[string]string{"state": "idle"}}},
|
||||||
|
expectedMetrics: regexp.MustCompile(`^# HELP windows_performancecounter_collector_duration_seconds windows_exporter: Duration of an performancecounter child collection.
|
||||||
|
# TYPE windows_performancecounter_collector_duration_seconds gauge
|
||||||
|
windows_performancecounter_collector_duration_seconds\{collector="processor_information_formatted"} [0-9.e+-]+
|
||||||
|
# HELP windows_performancecounter_collector_success windows_exporter: Whether a performancecounter child collector was successful.
|
||||||
|
# TYPE windows_performancecounter_collector_success gauge
|
||||||
|
windows_performancecounter_collector_success\{collector="processor_information_formatted"} 1
|
||||||
|
# HELP windows_performancecounter_processor_information_processor_time windows_exporter: custom Performance Counter metric
|
||||||
|
# TYPE windows_performancecounter_processor_information_processor_time gauge
|
||||||
|
windows_performancecounter_processor_information_processor_time\{core="0,0",state="active"} [0-9]+
|
||||||
|
windows_performancecounter_processor_information_processor_time\{core="0,0",state="idle"} [0-9]+
|
||||||
.*`),
|
.*`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
object: "Processor Information",
|
object: "Processor Information",
|
||||||
|
counterType: pdh.CounterTypeRaw,
|
||||||
instances: nil,
|
instances: nil,
|
||||||
instanceLabel: "",
|
instanceLabel: "",
|
||||||
buildErr: "object name is required",
|
buildErr: "object name is required",
|
||||||
@@ -122,6 +147,7 @@ windows_performancecounter_processor_information_processor_time\{core="0,0",stat
|
|||||||
{
|
{
|
||||||
name: "double_counter",
|
name: "double_counter",
|
||||||
object: "Memory",
|
object: "Memory",
|
||||||
|
counterType: pdh.CounterTypeRaw,
|
||||||
instances: nil,
|
instances: nil,
|
||||||
buildErr: "counter name Available Bytes is duplicated",
|
buildErr: "counter name Available Bytes is duplicated",
|
||||||
counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}, {Name: "Available Bytes", Type: "gauge"}},
|
counters: []performancecounter.Counter{{Name: "Available Bytes", Type: "gauge"}, {Name: "Available Bytes", Type: "gauge"}},
|
||||||
@@ -130,11 +156,21 @@ windows_performancecounter_processor_information_processor_time\{core="0,0",stat
|
|||||||
{
|
{
|
||||||
name: "counter with spaces and brackets",
|
name: "counter with spaces and brackets",
|
||||||
object: "invalid",
|
object: "invalid",
|
||||||
|
counterType: pdh.CounterTypeRaw,
|
||||||
instances: nil,
|
instances: nil,
|
||||||
buildErr: pdh.NewPdhError(pdh.CstatusNoObject).Error(),
|
buildErr: pdh.NewPdhError(pdh.CstatusNoObject).Error(),
|
||||||
counters: []performancecounter.Counter{{Name: "Total Memory Usage --- Non-Paged Pool", Type: "counter"}, {Name: "Max Session Input Delay (ms)", Type: "counter"}},
|
counters: []performancecounter.Counter{{Name: "Total Memory Usage --- Non-Paged Pool", Type: "counter"}, {Name: "Max Session Input Delay (ms)", Type: "counter"}},
|
||||||
expectedMetrics: nil,
|
expectedMetrics: nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid counter type",
|
||||||
|
object: "invalid",
|
||||||
|
counterType: "invalid",
|
||||||
|
instances: nil,
|
||||||
|
buildErr: "invalid result type: ",
|
||||||
|
counters: []performancecounter.Counter{{Name: "Total Memory Usage --- Non-Paged Pool", Type: "counter"}, {Name: "Max Session Input Delay (ms)", Type: "counter"}},
|
||||||
|
expectedMetrics: nil,
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -144,6 +180,7 @@ windows_performancecounter_processor_information_processor_time\{core="0,0",stat
|
|||||||
{
|
{
|
||||||
Name: tc.name,
|
Name: tc.name,
|
||||||
Object: tc.object,
|
Object: tc.object,
|
||||||
|
Type: tc.counterType,
|
||||||
Instances: tc.instances,
|
Instances: tc.instances,
|
||||||
InstanceLabel: tc.instanceLabel,
|
InstanceLabel: tc.instanceLabel,
|
||||||
Counters: tc.counters,
|
Counters: tc.counters,
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Object struct {
|
type Object struct {
|
||||||
Name string `json:"name" yaml:"name"`
|
Name string `json:"name" yaml:"name"`
|
||||||
Object string `json:"object" yaml:"object"`
|
Object string `json:"object" yaml:"object"`
|
||||||
Instances []string `json:"instances" yaml:"instances"`
|
Type pdh.CounterType `json:"type" yaml:"type"`
|
||||||
Counters []Counter `json:"counters" yaml:"counters"`
|
Instances []string `json:"instances" yaml:"instances"`
|
||||||
InstanceLabel string `json:"instance_label" yaml:"instance_label"` //nolint:tagliatelle
|
Counters []Counter `json:"counters" yaml:"counters"`
|
||||||
|
InstanceLabel string `json:"instance_label" yaml:"instance_label"` //nolint:tagliatelle
|
||||||
|
|
||||||
collector *pdh.Collector
|
collector *pdh.Collector
|
||||||
perfDataObject any
|
perfDataObject any
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("PhysicalDisk", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "PhysicalDisk", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create PhysicalDisk collector: %w", err)
|
return fmt.Errorf("failed to create PhysicalDisk collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
|||||||
c.miSession = miSession
|
c.miSession = miSession
|
||||||
|
|
||||||
c.collectorVersion = 2
|
c.collectorVersion = 2
|
||||||
c.perfDataCollectorV2, err = pdh.NewCollector[perfDataCounterValuesV2]("Process V2", pdh.InstancesAll)
|
c.perfDataCollectorV2, err = pdh.NewCollector[perfDataCounterValuesV2](pdh.CounterTypeRaw, "Process V2", pdh.InstancesAll)
|
||||||
|
|
||||||
if errors.Is(err, pdh.NewPdhError(pdh.CstatusNoObject)) {
|
if errors.Is(err, pdh.NewPdhError(pdh.CstatusNoObject)) {
|
||||||
c.collectorVersion = 1
|
c.collectorVersion = 1
|
||||||
|
|||||||
@@ -104,12 +104,12 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(*slog.Logger, *mi.Session) error {
|
func (c *Collector) Build(*slog.Logger, *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorNetwork, err = pdh.NewCollector[perfDataCounterValuesNetwork]("RemoteFX Network", pdh.InstancesAll)
|
c.perfDataCollectorNetwork, err = pdh.NewCollector[perfDataCounterValuesNetwork](pdh.CounterTypeRaw, "RemoteFX Network", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create RemoteFX Network collector: %w", err)
|
return fmt.Errorf("failed to create RemoteFX Network collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.perfDataCollectorGraphics, err = pdh.NewCollector[perfDataCounterValuesGraphics]("RemoteFX Graphics", pdh.InstancesAll)
|
c.perfDataCollectorGraphics, err = pdh.NewCollector[perfDataCounterValuesGraphics](pdh.CounterTypeRaw, "RemoteFX Graphics", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create RemoteFX Graphics collector: %w", err)
|
return fmt.Errorf("failed to create RemoteFX Graphics collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("SMB Server Shares", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "SMB Server Shares", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create SMB Server Shares collector: %w", err)
|
return fmt.Errorf("failed to create SMB Server Shares collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("SMB Client Shares", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "SMB Client Shares", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create SMB Client Shares collector: %w", err)
|
return fmt.Errorf("failed to create SMB Client Shares collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("SMTP Server", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "SMTP Server", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create SMTP Server collector: %w", err)
|
return fmt.Errorf("failed to create SMTP Server collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("System", nil)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "System", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create System collector: %w", err)
|
return fmt.Errorf("failed to create System collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,12 +120,12 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector4, err = pdh.NewCollector[perfDataCounterValues]("TCPv4", nil)
|
c.perfDataCollector4, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "TCPv4", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create TCPv4 collector: %w", err)
|
return fmt.Errorf("failed to create TCPv4 collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.perfDataCollector6, err = pdh.NewCollector[perfDataCounterValues]("TCPv6", nil)
|
c.perfDataCollector6, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "TCPv6", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create TCPv6 collector: %w", err)
|
return fmt.Errorf("failed to create TCPv6 collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorTerminalServicesSession, err = pdh.NewCollector[perfDataCounterValuesTerminalServicesSession]("Terminal Services Session", pdh.InstancesAll)
|
c.perfDataCollectorTerminalServicesSession, err = pdh.NewCollector[perfDataCounterValuesTerminalServicesSession](pdh.CounterTypeRaw, "Terminal Services Session", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Terminal Services Session collector: %w", err)
|
return fmt.Errorf("failed to create Terminal Services Session collector: %w", err)
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
|||||||
if c.connectionBrokerEnabled {
|
if c.connectionBrokerEnabled {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollectorBroker, err = pdh.NewCollector[perfDataCounterValuesBroker]("Remote Desktop Connection Broker Counterset", pdh.InstancesAll)
|
c.perfDataCollectorBroker, err = pdh.NewCollector[perfDataCounterValuesBroker](pdh.CounterTypeRaw, "Remote Desktop Connection Broker Counterset", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Remote Desktop Connection Broker Counterset collector: %w", err)
|
return fmt.Errorf("failed to create Remote Desktop Connection Broker Counterset collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Thermal Zone Information", pdh.InstancesAll)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Thermal Zone Information", pdh.InstancesAll)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Thermal Zone Information collector: %w", err)
|
return fmt.Errorf("failed to create Thermal Zone Information collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues]("Windows Time Service", nil)
|
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "Windows Time Service", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create Windows Time Service collector: %w", err)
|
return fmt.Errorf("failed to create Windows Time Service collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.perfDataCollector4, err = pdh.NewCollector[perfDataCounterValues]("UDPv4", nil)
|
c.perfDataCollector4, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "UDPv4", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create UDPv4 collector: %w", err)
|
return fmt.Errorf("failed to create UDPv4 collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.perfDataCollector6, err = pdh.NewCollector[perfDataCounterValues]("UDPv6", nil)
|
c.perfDataCollector6, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "UDPv6", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create UDPv6 collector: %w", err)
|
return fmt.Errorf("failed to create UDPv6 collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,12 +98,12 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
errs []error
|
errs []error
|
||||||
)
|
)
|
||||||
|
|
||||||
c.perfDataCollectorCPU, err = pdh.NewCollector[perfDataCounterValuesCPU]("VM Processor", pdh.InstancesTotal)
|
c.perfDataCollectorCPU, err = pdh.NewCollector[perfDataCounterValuesCPU](pdh.CounterTypeRaw, "VM Processor", pdh.InstancesTotal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create VM Processor collector: %w", err))
|
errs = append(errs, fmt.Errorf("failed to create VM Processor collector: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
c.perfDataCollectorMemory, err = pdh.NewCollector[perfDataCounterValuesMemory]("VM Memory", nil)
|
c.perfDataCollectorMemory, err = pdh.NewCollector[perfDataCounterValuesMemory](pdh.CounterTypeRaw, "VM Memory", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to create VM Memory collector: %w", err))
|
errs = append(errs, fmt.Errorf("failed to create VM Memory collector: %w", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,13 +63,13 @@ type Counter struct {
|
|||||||
FieldIndexSecondValue int
|
FieldIndexSecondValue int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCollector[T any](object string, instances []string) (*Collector, error) {
|
func NewCollector[T any](resultType CounterType, object string, instances []string) (*Collector, error) {
|
||||||
valueType := reflect.TypeFor[T]()
|
valueType := reflect.TypeFor[T]()
|
||||||
|
|
||||||
return NewCollectorWithReflection(object, instances, valueType)
|
return NewCollectorWithReflection(resultType, object, instances, valueType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCollectorWithReflection(object string, instances []string, valueType reflect.Type) (*Collector, error) {
|
func NewCollectorWithReflection(resultType CounterType, object string, instances []string, valueType reflect.Type) (*Collector, error) {
|
||||||
var handle pdhQueryHandle
|
var handle pdhQueryHandle
|
||||||
|
|
||||||
if ret := OpenQuery(0, 0, &handle); ret != ErrorSuccess {
|
if ret := OpenQuery(0, 0, &handle); ret != ErrorSuccess {
|
||||||
@@ -80,6 +80,10 @@ func NewCollectorWithReflection(object string, instances []string, valueType ref
|
|||||||
instances = []string{InstanceEmpty}
|
instances = []string{InstanceEmpty}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resultType != CounterTypeRaw && resultType != CounterTypeFormatted {
|
||||||
|
return nil, fmt.Errorf("invalid result type: %v", resultType)
|
||||||
|
}
|
||||||
|
|
||||||
collector := &Collector{
|
collector := &Collector{
|
||||||
object: object,
|
object: object,
|
||||||
counters: make(map[string]Counter, valueType.NumField()),
|
counters: make(map[string]Counter, valueType.NumField()),
|
||||||
@@ -209,7 +213,11 @@ func NewCollectorWithReflection(object string, instances []string, valueType ref
|
|||||||
collector.collectCh = make(chan any)
|
collector.collectCh = make(chan any)
|
||||||
collector.errorCh = make(chan error)
|
collector.errorCh = make(chan error)
|
||||||
|
|
||||||
go collector.collectRoutine()
|
if resultType == CounterTypeRaw {
|
||||||
|
go collector.collectWorkerRaw()
|
||||||
|
} else {
|
||||||
|
go collector.collectWorkerFormatted()
|
||||||
|
}
|
||||||
|
|
||||||
// Collect initial data because some counters need to be read twice to get the correct value.
|
// Collect initial data because some counters need to be read twice to get the correct value.
|
||||||
collectValues := reflect.New(reflect.SliceOf(valueType)).Elem()
|
collectValues := reflect.New(reflect.SliceOf(valueType)).Elem()
|
||||||
@@ -254,7 +262,7 @@ func (c *Collector) Collect(dst any) error {
|
|||||||
return <-c.errorCh
|
return <-c.errorCh
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) collectRoutine() {
|
func (c *Collector) collectWorkerRaw() {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
itemCount uint32
|
itemCount uint32
|
||||||
@@ -310,7 +318,11 @@ func (c *Collector) collectRoutine() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := NewPdhError(ret); ret != MoreData && !isKnownCounterDataError(err) {
|
if err := NewPdhError(ret); ret != MoreData {
|
||||||
|
if isKnownCounterDataError(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf("GetRawCounterArray: %w", err)
|
return fmt.Errorf("GetRawCounterArray: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,6 +423,142 @@ func (c *Collector) collectRoutine() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Collector) collectWorkerFormatted() {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
itemCount uint32
|
||||||
|
items []FmtCounterValueItemDouble
|
||||||
|
bytesNeeded uint32
|
||||||
|
)
|
||||||
|
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
|
||||||
|
for data := range c.collectCh {
|
||||||
|
err = (func() error {
|
||||||
|
if ret := CollectQueryData(c.handle); ret != ErrorSuccess {
|
||||||
|
return fmt.Errorf("failed to collect query data: %w", NewPdhError(ret))
|
||||||
|
}
|
||||||
|
|
||||||
|
dv := reflect.ValueOf(data)
|
||||||
|
if dv.Kind() != reflect.Ptr || dv.IsNil() {
|
||||||
|
return fmt.Errorf("expected a pointer, got %s: %w", dv.Kind(), mi.ErrInvalidEntityType)
|
||||||
|
}
|
||||||
|
|
||||||
|
dv = dv.Elem()
|
||||||
|
|
||||||
|
if dv.Kind() != reflect.Slice {
|
||||||
|
return fmt.Errorf("expected a pointer to a slice, got %s: %w", dv.Kind(), mi.ErrInvalidEntityType)
|
||||||
|
}
|
||||||
|
|
||||||
|
elemType := dv.Type().Elem()
|
||||||
|
|
||||||
|
if elemType.Kind() != reflect.Struct {
|
||||||
|
return fmt.Errorf("expected a pointer to a slice of structs, got a slice of %s: %w", elemType.Kind(), mi.ErrInvalidEntityType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dv.Len() != 0 {
|
||||||
|
dv.Set(reflect.MakeSlice(dv.Type(), 0, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
dv.Clear()
|
||||||
|
|
||||||
|
elemValue := reflect.ValueOf(reflect.New(elemType).Interface()).Elem()
|
||||||
|
|
||||||
|
indexMap := map[string]int{}
|
||||||
|
stringMap := map[*uint16]string{}
|
||||||
|
|
||||||
|
for _, counter := range c.counters {
|
||||||
|
for _, instance := range counter.Instances {
|
||||||
|
// Get the info with the current buffer size
|
||||||
|
bytesNeeded = uint32(cap(buf))
|
||||||
|
|
||||||
|
for {
|
||||||
|
ret := GetFormattedCounterArrayDouble(instance, &bytesNeeded, &itemCount, &buf[0])
|
||||||
|
|
||||||
|
if ret == ErrorSuccess {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := NewPdhError(ret); ret != MoreData {
|
||||||
|
if isKnownCounterDataError(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("GetFormattedCounterArrayDouble: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytesNeeded <= uint32(cap(buf)) {
|
||||||
|
return fmt.Errorf("GetFormattedCounterArrayDouble reports buffer too small (%d), but buffer is large enough (%d): %w", uint32(cap(buf)), bytesNeeded, NewPdhError(ret))
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = make([]byte, bytesNeeded)
|
||||||
|
}
|
||||||
|
|
||||||
|
items = unsafe.Slice((*FmtCounterValueItemDouble)(unsafe.Pointer(&buf[0])), itemCount)
|
||||||
|
|
||||||
|
var (
|
||||||
|
instanceName string
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
if item.FmtValue.CStatus != CstatusValidData && item.FmtValue.CStatus != CstatusNewData {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if instanceName, ok = stringMap[item.SzName]; !ok {
|
||||||
|
instanceName = windows.UTF16PtrToString(item.SzName)
|
||||||
|
stringMap[item.SzName] = instanceName
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(instanceName, InstanceTotal) && !c.totalCounterRequested {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if instanceName == "" || instanceName == "*" {
|
||||||
|
instanceName = InstanceEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
index int
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
|
||||||
|
if index, ok = indexMap[instanceName]; !ok {
|
||||||
|
index = dv.Len()
|
||||||
|
indexMap[instanceName] = index
|
||||||
|
|
||||||
|
if c.nameIndexValue != -1 {
|
||||||
|
elemValue.Field(c.nameIndexValue).SetString(instanceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.metricsTypeIndexValue != -1 {
|
||||||
|
elemValue.Field(c.metricsTypeIndexValue).Set(reflect.ValueOf(prometheus.GaugeValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
dv.Set(reflect.Append(dv, elemValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
if counter.FieldIndexValue != -1 {
|
||||||
|
dv.Index(index).
|
||||||
|
Field(counter.FieldIndexValue).
|
||||||
|
SetFloat(item.FmtValue.DoubleValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dv.Len() == 0 {
|
||||||
|
return ErrNoData
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})()
|
||||||
|
|
||||||
|
c.errorCh <- err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Collector) Close() {
|
func (c *Collector) Close() {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ type processFull struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkTestCollector(b *testing.B) {
|
func BenchmarkTestCollector(b *testing.B) {
|
||||||
performanceData, err := pdh.NewCollector[processFull]("Process", []string{"*"})
|
performanceData, err := pdh.NewCollector[processFull](pdh.CounterTypeRaw, "Process", []string{"*"})
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
|
|
||||||
var data []processFull
|
var data []processFull
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func TestCollector(t *testing.T) {
|
|||||||
t.Run(tc.object, func(t *testing.T) {
|
t.Run(tc.object, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
performanceData, err := pdh.NewCollector[process](tc.object, tc.instances)
|
performanceData, err := pdh.NewCollector[process](pdh.CounterTypeRaw, tc.object, tc.instances)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ func GetFormattedCounterValueDouble(hCounter pdhCounterHandle, lpdwType *uint32,
|
|||||||
func GetFormattedCounterArrayDouble(hCounter pdhCounterHandle, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *byte) uint32 {
|
func GetFormattedCounterArrayDouble(hCounter pdhCounterHandle, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *byte) uint32 {
|
||||||
ret, _, _ := pdhGetFormattedCounterArrayW.Call(
|
ret, _, _ := pdhGetFormattedCounterArrayW.Call(
|
||||||
uintptr(hCounter),
|
uintptr(hCounter),
|
||||||
uintptr(FmtDouble|FmtNocap100),
|
uintptr(FmtDouble),
|
||||||
uintptr(unsafe.Pointer(lpdwBufferSize)),
|
uintptr(unsafe.Pointer(lpdwBufferSize)),
|
||||||
uintptr(unsafe.Pointer(lpdwBufferCount)),
|
uintptr(unsafe.Pointer(lpdwBufferCount)),
|
||||||
uintptr(unsafe.Pointer(itemBuffer)))
|
uintptr(unsafe.Pointer(itemBuffer)))
|
||||||
|
|||||||
@@ -20,6 +20,13 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CounterType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
CounterTypeRaw CounterType = "raw"
|
||||||
|
CounterTypeFormatted CounterType = "formatted"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
InstanceEmpty = "------"
|
InstanceEmpty = "------"
|
||||||
InstanceTotal = "_Total"
|
InstanceTotal = "_Total"
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewWithFlags To be called by the exporter for collector initialization before running kingpin.Parse.
|
// NewWithFlags To be called by the exporter for collector initialization before running kingpin.Parse.
|
||||||
@@ -231,6 +232,7 @@ func (c *Collection) Build(logger *slog.Logger) error {
|
|||||||
|
|
||||||
for err := range errCh {
|
for err := range errCh {
|
||||||
if errors.Is(err, pdh.ErrNoData) ||
|
if errors.Is(err, pdh.ErrNoData) ||
|
||||||
|
errors.Is(err, registry.ErrNotExist) ||
|
||||||
errors.Is(err, pdh.NewPdhError(pdh.CstatusNoObject)) ||
|
errors.Is(err, pdh.NewPdhError(pdh.CstatusNoObject)) ||
|
||||||
errors.Is(err, pdh.NewPdhError(pdh.CstatusNoCounter)) ||
|
errors.Is(err, pdh.NewPdhError(pdh.CstatusNoCounter)) ||
|
||||||
errors.Is(err, mi.MI_RESULT_INVALID_NAMESPACE) {
|
errors.Is(err, mi.MI_RESULT_INVALID_NAMESPACE) {
|
||||||
|
|||||||
Reference in New Issue
Block a user