collector: derive the collector maps from one registration table (#2730)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-15 21:19:47 +00:00
committed by GitHub
parent b914dbbf6e
commit 379b1553bd
10 changed files with 805 additions and 231 deletions
+4 -101
View File
@@ -28,56 +28,6 @@ import (
gotime "time"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/collector/ad"
"github.com/prometheus-community/windows_exporter/internal/collector/adcs"
"github.com/prometheus-community/windows_exporter/internal/collector/adfs"
"github.com/prometheus-community/windows_exporter/internal/collector/cache"
"github.com/prometheus-community/windows_exporter/internal/collector/container"
"github.com/prometheus-community/windows_exporter/internal/collector/cpu"
"github.com/prometheus-community/windows_exporter/internal/collector/cpu_info"
"github.com/prometheus-community/windows_exporter/internal/collector/dfsr"
"github.com/prometheus-community/windows_exporter/internal/collector/dhcp"
"github.com/prometheus-community/windows_exporter/internal/collector/diskdrive"
"github.com/prometheus-community/windows_exporter/internal/collector/dmi"
"github.com/prometheus-community/windows_exporter/internal/collector/dns"
"github.com/prometheus-community/windows_exporter/internal/collector/exchange"
"github.com/prometheus-community/windows_exporter/internal/collector/file"
"github.com/prometheus-community/windows_exporter/internal/collector/fsrmquota"
"github.com/prometheus-community/windows_exporter/internal/collector/gpu"
"github.com/prometheus-community/windows_exporter/internal/collector/hyperv"
"github.com/prometheus-community/windows_exporter/internal/collector/iis"
"github.com/prometheus-community/windows_exporter/internal/collector/license"
"github.com/prometheus-community/windows_exporter/internal/collector/logical_disk"
"github.com/prometheus-community/windows_exporter/internal/collector/memory"
"github.com/prometheus-community/windows_exporter/internal/collector/mscluster"
"github.com/prometheus-community/windows_exporter/internal/collector/msmq"
"github.com/prometheus-community/windows_exporter/internal/collector/mssql"
"github.com/prometheus-community/windows_exporter/internal/collector/net"
"github.com/prometheus-community/windows_exporter/internal/collector/netframework"
"github.com/prometheus-community/windows_exporter/internal/collector/nps"
"github.com/prometheus-community/windows_exporter/internal/collector/os"
"github.com/prometheus-community/windows_exporter/internal/collector/pagefile"
"github.com/prometheus-community/windows_exporter/internal/collector/performancecounter"
"github.com/prometheus-community/windows_exporter/internal/collector/physical_disk"
"github.com/prometheus-community/windows_exporter/internal/collector/printer"
"github.com/prometheus-community/windows_exporter/internal/collector/process"
"github.com/prometheus-community/windows_exporter/internal/collector/registry"
"github.com/prometheus-community/windows_exporter/internal/collector/remote_fx"
"github.com/prometheus-community/windows_exporter/internal/collector/scheduled_task"
"github.com/prometheus-community/windows_exporter/internal/collector/service"
"github.com/prometheus-community/windows_exporter/internal/collector/smb"
"github.com/prometheus-community/windows_exporter/internal/collector/smbclient"
"github.com/prometheus-community/windows_exporter/internal/collector/smtp"
"github.com/prometheus-community/windows_exporter/internal/collector/storage_spaces"
"github.com/prometheus-community/windows_exporter/internal/collector/system"
"github.com/prometheus-community/windows_exporter/internal/collector/tcp"
"github.com/prometheus-community/windows_exporter/internal/collector/terminal_services"
"github.com/prometheus-community/windows_exporter/internal/collector/textfile"
"github.com/prometheus-community/windows_exporter/internal/collector/time"
"github.com/prometheus-community/windows_exporter/internal/collector/udp"
"github.com/prometheus-community/windows_exporter/internal/collector/update"
"github.com/prometheus-community/windows_exporter/internal/collector/vmware"
"github.com/prometheus-community/windows_exporter/internal/collector/wmi"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/pdh"
"github.com/prometheus-community/windows_exporter/internal/types"
@@ -100,57 +50,10 @@ func NewWithFlags(app *kingpin.Application) *Collection {
//
//goland:noinspection GoUnusedExportedFunction
func NewWithConfig(config Config) *Collection {
collectors := Map{}
collectors[ad.Name] = ad.New(&config.AD)
collectors[adcs.Name] = adcs.New(&config.ADCS)
collectors[adfs.Name] = adfs.New(&config.ADFS)
collectors[cache.Name] = cache.New(&config.Cache)
collectors[container.Name] = container.New(&config.Container)
collectors[cpu.Name] = cpu.New(&config.CPU)
collectors[cpu_info.Name] = cpu_info.New(&config.CPUInfo)
collectors[dfsr.Name] = dfsr.New(&config.DFSR)
collectors[dhcp.Name] = dhcp.New(&config.Dhcp)
collectors[diskdrive.Name] = diskdrive.New(&config.DiskDrive)
collectors[dmi.Name] = dmi.New(&config.DMI)
collectors[dns.Name] = dns.New(&config.DNS)
collectors[exchange.Name] = exchange.New(&config.Exchange)
collectors[file.Name] = file.New(&config.File)
collectors[fsrmquota.Name] = fsrmquota.New(&config.Fsrmquota)
collectors[gpu.Name] = gpu.New(&config.GPU)
collectors[hyperv.Name] = hyperv.New(&config.HyperV)
collectors[iis.Name] = iis.New(&config.IIS)
collectors[license.Name] = license.New(&config.License)
collectors[logical_disk.Name] = logical_disk.New(&config.LogicalDisk)
collectors[memory.Name] = memory.New(&config.Memory)
collectors[mscluster.Name] = mscluster.New(&config.MSCluster)
collectors[msmq.Name] = msmq.New(&config.Msmq)
collectors[mssql.Name] = mssql.New(&config.Mssql)
collectors[net.Name] = net.New(&config.Net)
collectors[netframework.Name] = netframework.New(&config.NetFramework)
collectors[nps.Name] = nps.New(&config.Nps)
collectors[os.Name] = os.New(&config.OS)
collectors[pagefile.Name] = pagefile.New(&config.Paging)
collectors[performancecounter.Name] = performancecounter.New(&config.PerformanceCounter)
collectors[physical_disk.Name] = physical_disk.New(&config.PhysicalDisk)
collectors[printer.Name] = printer.New(&config.Printer)
collectors[process.Name] = process.New(&config.Process)
collectors[registry.Name] = registry.New(&config.Registry)
collectors[remote_fx.Name] = remote_fx.New(&config.RemoteFx)
collectors[scheduled_task.Name] = scheduled_task.New(&config.ScheduledTask)
collectors[service.Name] = service.New(&config.Service)
collectors[smb.Name] = smb.New(&config.SMB)
collectors[smbclient.Name] = smbclient.New(&config.SMBClient)
collectors[smtp.Name] = smtp.New(&config.SMTP)
collectors[storage_spaces.Name] = storage_spaces.New(&config.StorageSpaces)
collectors[system.Name] = system.New(&config.System)
collectors[tcp.Name] = tcp.New(&config.TCP)
collectors[terminal_services.Name] = terminal_services.New(&config.TerminalServices)
collectors[textfile.Name] = textfile.New(&config.Textfile)
collectors[time.Name] = time.New(&config.Time)
collectors[udp.Name] = udp.New(&config.UDP)
collectors[update.Name] = update.New(&config.Update)
collectors[vmware.Name] = vmware.New(&config.Vmware)
collectors[wmi.Name] = wmi.New(&config.WMI)
collectors := make(Map, len(registrations))
for _, r := range registrations {
collectors[r.name] = r.newWithConfig(&config)
}
return New(collectors)
}
+10 -54
View File
@@ -99,7 +99,7 @@ type Config struct {
NetFramework netframework.Config `yaml:"netframework"`
Nps nps.Config `yaml:"nps"`
OS os.Config `yaml:"os"`
Paging pagefile.Config `yaml:"paging"`
Paging pagefile.Config `yaml:"pagefile"`
PerformanceCounter performancecounter.Config `yaml:"performancecounter"`
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
Printer printer.Config `yaml:"printer"`
@@ -109,7 +109,7 @@ type Config struct {
ScheduledTask scheduled_task.Config `yaml:"scheduled_task"`
Service service.Config `yaml:"service"`
SMB smb.Config `yaml:"smb"`
SMBClient smbclient.Config `yaml:"smb_client"`
SMBClient smbclient.Config `yaml:"smbclient"`
SMTP smtp.Config `yaml:"smtp"`
StorageSpaces storage_spaces.Config `yaml:"storage_spaces"`
System system.Config `yaml:"system"`
@@ -127,55 +127,11 @@ type Config struct {
//
//nolint:gochecknoglobals
//goland:noinspection GoUnusedGlobalVariable
var ConfigDefaults = Config{
AD: ad.ConfigDefaults,
ADCS: adcs.ConfigDefaults,
ADFS: adfs.ConfigDefaults,
Cache: cache.ConfigDefaults,
Container: container.ConfigDefaults,
CPU: cpu.ConfigDefaults,
CPUInfo: cpu_info.ConfigDefaults,
DFSR: dfsr.ConfigDefaults,
Dhcp: dhcp.ConfigDefaults,
DiskDrive: diskdrive.ConfigDefaults,
DMI: dmi.ConfigDefaults,
DNS: dns.ConfigDefaults,
Exchange: exchange.ConfigDefaults,
File: file.ConfigDefaults,
Fsrmquota: fsrmquota.ConfigDefaults,
GPU: gpu.ConfigDefaults,
HyperV: hyperv.ConfigDefaults,
IIS: iis.ConfigDefaults,
License: license.ConfigDefaults,
LogicalDisk: logical_disk.ConfigDefaults,
Memory: memory.ConfigDefaults,
MSCluster: mscluster.ConfigDefaults,
Msmq: msmq.ConfigDefaults,
Mssql: mssql.ConfigDefaults,
Net: net.ConfigDefaults,
NetFramework: netframework.ConfigDefaults,
Nps: nps.ConfigDefaults,
OS: os.ConfigDefaults,
Paging: pagefile.ConfigDefaults,
PerformanceCounter: performancecounter.ConfigDefaults,
PhysicalDisk: physical_disk.ConfigDefaults,
Printer: printer.ConfigDefaults,
Process: process.ConfigDefaults,
Registry: registry.ConfigDefaults,
RemoteFx: remote_fx.ConfigDefaults,
ScheduledTask: scheduled_task.ConfigDefaults,
Service: service.ConfigDefaults,
SMB: smb.ConfigDefaults,
SMBClient: smbclient.ConfigDefaults,
SMTP: smtp.ConfigDefaults,
StorageSpaces: storage_spaces.ConfigDefaults,
System: system.ConfigDefaults,
TCP: tcp.ConfigDefaults,
TerminalServices: terminal_services.ConfigDefaults,
Textfile: textfile.ConfigDefaults,
Time: time.ConfigDefaults,
UDP: udp.ConfigDefaults,
Update: update.ConfigDefaults,
Vmware: vmware.ConfigDefaults,
WMI: wmi.ConfigDefaults,
}
var ConfigDefaults = func() Config {
var config Config
for _, r := range registrations {
r.setDefaults(&config)
}
return config
}()
+101 -52
View File
@@ -74,65 +74,114 @@ import (
"github.com/prometheus-community/windows_exporter/internal/collector/wmi"
)
// registration ties a collector name to its constructors, its field in
// [Config] and its default configuration. It is the single source of
// [BuildersWithFlags], [NewWithConfig] and [ConfigDefaults].
type registration struct {
name string
newWithFlags BuilderWithFlags[Collector]
newWithConfig func(config *Config) Collector
setDefaults func(config *Config)
// field returns the address of the collector's field in config. Tests
// use it to match the registrations to the fields of [Config].
field func(config *Config) any
}
// register returns the registration of a collector. Its type parameters
// ensure that the constructors, the defaults and the [Config] field use the
// same configuration type.
func register[C Collector, T any](
name string,
newWithConfig func(*T) C,
newWithFlags BuilderWithFlags[C],
defaults T,
field func(*Config) *T,
) registration {
return registration{
name: name,
newWithFlags: NewBuilderWithFlags(newWithFlags),
newWithConfig: func(config *Config) Collector { return newWithConfig(field(config)) },
setDefaults: func(config *Config) { *field(config) = defaults },
field: func(config *Config) any { return field(config) },
}
}
// registrations lists every built-in collector. A new collector needs its
// field in [Config], its documentation in docs/collector.<name>.md and one
// entry here.
//
//nolint:gochecknoglobals
var registrations = []registration{
register(ad.Name, ad.New, ad.NewWithFlags, ad.ConfigDefaults, func(c *Config) *ad.Config { return &c.AD }),
register(adcs.Name, adcs.New, adcs.NewWithFlags, adcs.ConfigDefaults, func(c *Config) *adcs.Config { return &c.ADCS }),
register(adfs.Name, adfs.New, adfs.NewWithFlags, adfs.ConfigDefaults, func(c *Config) *adfs.Config { return &c.ADFS }),
register(cache.Name, cache.New, cache.NewWithFlags, cache.ConfigDefaults, func(c *Config) *cache.Config { return &c.Cache }),
register(container.Name, container.New, container.NewWithFlags, container.ConfigDefaults, func(c *Config) *container.Config { return &c.Container }),
register(cpu.Name, cpu.New, cpu.NewWithFlags, cpu.ConfigDefaults, func(c *Config) *cpu.Config { return &c.CPU }),
register(cpu_info.Name, cpu_info.New, cpu_info.NewWithFlags, cpu_info.ConfigDefaults, func(c *Config) *cpu_info.Config { return &c.CPUInfo }),
register(dfsr.Name, dfsr.New, dfsr.NewWithFlags, dfsr.ConfigDefaults, func(c *Config) *dfsr.Config { return &c.DFSR }),
register(dhcp.Name, dhcp.New, dhcp.NewWithFlags, dhcp.ConfigDefaults, func(c *Config) *dhcp.Config { return &c.Dhcp }),
register(diskdrive.Name, diskdrive.New, diskdrive.NewWithFlags, diskdrive.ConfigDefaults, func(c *Config) *diskdrive.Config { return &c.DiskDrive }),
register(dmi.Name, dmi.New, dmi.NewWithFlags, dmi.ConfigDefaults, func(c *Config) *dmi.Config { return &c.DMI }),
register(dns.Name, dns.New, dns.NewWithFlags, dns.ConfigDefaults, func(c *Config) *dns.Config { return &c.DNS }),
register(exchange.Name, exchange.New, exchange.NewWithFlags, exchange.ConfigDefaults, func(c *Config) *exchange.Config { return &c.Exchange }),
register(file.Name, file.New, file.NewWithFlags, file.ConfigDefaults, func(c *Config) *file.Config { return &c.File }),
register(fsrmquota.Name, fsrmquota.New, fsrmquota.NewWithFlags, fsrmquota.ConfigDefaults, func(c *Config) *fsrmquota.Config { return &c.Fsrmquota }),
register(gpu.Name, gpu.New, gpu.NewWithFlags, gpu.ConfigDefaults, func(c *Config) *gpu.Config { return &c.GPU }),
register(hyperv.Name, hyperv.New, hyperv.NewWithFlags, hyperv.ConfigDefaults, func(c *Config) *hyperv.Config { return &c.HyperV }),
register(iis.Name, iis.New, iis.NewWithFlags, iis.ConfigDefaults, func(c *Config) *iis.Config { return &c.IIS }),
register(license.Name, license.New, license.NewWithFlags, license.ConfigDefaults, func(c *Config) *license.Config { return &c.License }),
register(logical_disk.Name, logical_disk.New, logical_disk.NewWithFlags, logical_disk.ConfigDefaults, func(c *Config) *logical_disk.Config { return &c.LogicalDisk }),
register(memory.Name, memory.New, memory.NewWithFlags, memory.ConfigDefaults, func(c *Config) *memory.Config { return &c.Memory }),
register(mscluster.Name, mscluster.New, mscluster.NewWithFlags, mscluster.ConfigDefaults, func(c *Config) *mscluster.Config { return &c.MSCluster }),
register(msmq.Name, msmq.New, msmq.NewWithFlags, msmq.ConfigDefaults, func(c *Config) *msmq.Config { return &c.Msmq }),
register(mssql.Name, mssql.New, mssql.NewWithFlags, mssql.ConfigDefaults, func(c *Config) *mssql.Config { return &c.Mssql }),
register(net.Name, net.New, net.NewWithFlags, net.ConfigDefaults, func(c *Config) *net.Config { return &c.Net }),
register(netframework.Name, netframework.New, netframework.NewWithFlags, netframework.ConfigDefaults, func(c *Config) *netframework.Config { return &c.NetFramework }),
register(nps.Name, nps.New, nps.NewWithFlags, nps.ConfigDefaults, func(c *Config) *nps.Config { return &c.Nps }),
register(os.Name, os.New, os.NewWithFlags, os.ConfigDefaults, func(c *Config) *os.Config { return &c.OS }),
register(pagefile.Name, pagefile.New, pagefile.NewWithFlags, pagefile.ConfigDefaults, func(c *Config) *pagefile.Config { return &c.Paging }),
register(performancecounter.Name, performancecounter.New, performancecounter.NewWithFlags, performancecounter.ConfigDefaults, func(c *Config) *performancecounter.Config { return &c.PerformanceCounter }),
register(physical_disk.Name, physical_disk.New, physical_disk.NewWithFlags, physical_disk.ConfigDefaults, func(c *Config) *physical_disk.Config { return &c.PhysicalDisk }),
register(printer.Name, printer.New, printer.NewWithFlags, printer.ConfigDefaults, func(c *Config) *printer.Config { return &c.Printer }),
register(process.Name, process.New, process.NewWithFlags, process.ConfigDefaults, func(c *Config) *process.Config { return &c.Process }),
register(registry.Name, registry.New, registry.NewWithFlags, registry.ConfigDefaults, func(c *Config) *registry.Config { return &c.Registry }),
register(remote_fx.Name, remote_fx.New, remote_fx.NewWithFlags, remote_fx.ConfigDefaults, func(c *Config) *remote_fx.Config { return &c.RemoteFx }),
register(scheduled_task.Name, scheduled_task.New, scheduled_task.NewWithFlags, scheduled_task.ConfigDefaults, func(c *Config) *scheduled_task.Config { return &c.ScheduledTask }),
register(service.Name, service.New, service.NewWithFlags, service.ConfigDefaults, func(c *Config) *service.Config { return &c.Service }),
register(smb.Name, smb.New, smb.NewWithFlags, smb.ConfigDefaults, func(c *Config) *smb.Config { return &c.SMB }),
register(smbclient.Name, smbclient.New, smbclient.NewWithFlags, smbclient.ConfigDefaults, func(c *Config) *smbclient.Config { return &c.SMBClient }),
register(smtp.Name, smtp.New, smtp.NewWithFlags, smtp.ConfigDefaults, func(c *Config) *smtp.Config { return &c.SMTP }),
register(storage_spaces.Name, storage_spaces.New, storage_spaces.NewWithFlags, storage_spaces.ConfigDefaults, func(c *Config) *storage_spaces.Config { return &c.StorageSpaces }),
register(system.Name, system.New, system.NewWithFlags, system.ConfigDefaults, func(c *Config) *system.Config { return &c.System }),
register(tcp.Name, tcp.New, tcp.NewWithFlags, tcp.ConfigDefaults, func(c *Config) *tcp.Config { return &c.TCP }),
register(terminal_services.Name, terminal_services.New, terminal_services.NewWithFlags, terminal_services.ConfigDefaults, func(c *Config) *terminal_services.Config { return &c.TerminalServices }),
register(textfile.Name, textfile.New, textfile.NewWithFlags, textfile.ConfigDefaults, func(c *Config) *textfile.Config { return &c.Textfile }),
register(time.Name, time.New, time.NewWithFlags, time.ConfigDefaults, func(c *Config) *time.Config { return &c.Time }),
register(udp.Name, udp.New, udp.NewWithFlags, udp.ConfigDefaults, func(c *Config) *udp.Config { return &c.UDP }),
register(update.Name, update.New, update.NewWithFlags, update.ConfigDefaults, func(c *Config) *update.Config { return &c.Update }),
register(vmware.Name, vmware.New, vmware.NewWithFlags, vmware.ConfigDefaults, func(c *Config) *vmware.Config { return &c.Vmware }),
register(wmi.Name, wmi.New, wmi.NewWithFlags, wmi.ConfigDefaults, func(c *Config) *wmi.Config { return &c.WMI }),
}
func NewBuilderWithFlags[C Collector](fn BuilderWithFlags[C]) BuilderWithFlags[Collector] {
return func(app *kingpin.Application) Collector {
return fn(app)
}
}
// BuildersWithFlags holds the flag-based constructor of every built-in
// collector, keyed by the collector name.
//
//nolint:gochecknoglobals
var BuildersWithFlags = map[string]BuilderWithFlags[Collector]{
ad.Name: NewBuilderWithFlags(ad.NewWithFlags),
adcs.Name: NewBuilderWithFlags(adcs.NewWithFlags),
adfs.Name: NewBuilderWithFlags(adfs.NewWithFlags),
cache.Name: NewBuilderWithFlags(cache.NewWithFlags),
container.Name: NewBuilderWithFlags(container.NewWithFlags),
cpu.Name: NewBuilderWithFlags(cpu.NewWithFlags),
cpu_info.Name: NewBuilderWithFlags(cpu_info.NewWithFlags),
dfsr.Name: NewBuilderWithFlags(dfsr.NewWithFlags),
dhcp.Name: NewBuilderWithFlags(dhcp.NewWithFlags),
diskdrive.Name: NewBuilderWithFlags(diskdrive.NewWithFlags),
dmi.Name: NewBuilderWithFlags(dmi.NewWithFlags),
dns.Name: NewBuilderWithFlags(dns.NewWithFlags),
exchange.Name: NewBuilderWithFlags(exchange.NewWithFlags),
file.Name: NewBuilderWithFlags(file.NewWithFlags),
fsrmquota.Name: NewBuilderWithFlags(fsrmquota.NewWithFlags),
gpu.Name: NewBuilderWithFlags(gpu.NewWithFlags),
hyperv.Name: NewBuilderWithFlags(hyperv.NewWithFlags),
iis.Name: NewBuilderWithFlags(iis.NewWithFlags),
license.Name: NewBuilderWithFlags(license.NewWithFlags),
logical_disk.Name: NewBuilderWithFlags(logical_disk.NewWithFlags),
memory.Name: NewBuilderWithFlags(memory.NewWithFlags),
mscluster.Name: NewBuilderWithFlags(mscluster.NewWithFlags),
msmq.Name: NewBuilderWithFlags(msmq.NewWithFlags),
mssql.Name: NewBuilderWithFlags(mssql.NewWithFlags),
net.Name: NewBuilderWithFlags(net.NewWithFlags),
netframework.Name: NewBuilderWithFlags(netframework.NewWithFlags),
nps.Name: NewBuilderWithFlags(nps.NewWithFlags),
os.Name: NewBuilderWithFlags(os.NewWithFlags),
pagefile.Name: NewBuilderWithFlags(pagefile.NewWithFlags),
performancecounter.Name: NewBuilderWithFlags(performancecounter.NewWithFlags),
physical_disk.Name: NewBuilderWithFlags(physical_disk.NewWithFlags),
printer.Name: NewBuilderWithFlags(printer.NewWithFlags),
process.Name: NewBuilderWithFlags(process.NewWithFlags),
registry.Name: NewBuilderWithFlags(registry.NewWithFlags),
remote_fx.Name: NewBuilderWithFlags(remote_fx.NewWithFlags),
scheduled_task.Name: NewBuilderWithFlags(scheduled_task.NewWithFlags),
service.Name: NewBuilderWithFlags(service.NewWithFlags),
smb.Name: NewBuilderWithFlags(smb.NewWithFlags),
smbclient.Name: NewBuilderWithFlags(smbclient.NewWithFlags),
smtp.Name: NewBuilderWithFlags(smtp.NewWithFlags),
storage_spaces.Name: NewBuilderWithFlags(storage_spaces.NewWithFlags),
system.Name: NewBuilderWithFlags(system.NewWithFlags),
tcp.Name: NewBuilderWithFlags(tcp.NewWithFlags),
terminal_services.Name: NewBuilderWithFlags(terminal_services.NewWithFlags),
textfile.Name: NewBuilderWithFlags(textfile.NewWithFlags),
time.Name: NewBuilderWithFlags(time.NewWithFlags),
udp.Name: NewBuilderWithFlags(udp.NewWithFlags),
update.Name: NewBuilderWithFlags(update.NewWithFlags),
vmware.Name: NewBuilderWithFlags(vmware.NewWithFlags),
wmi.Name: NewBuilderWithFlags(wmi.NewWithFlags),
}
var BuildersWithFlags = func() map[string]BuilderWithFlags[Collector] {
builders := make(map[string]BuilderWithFlags[Collector], len(registrations))
for _, r := range registrations {
builders[r.name] = r.newWithFlags
}
return builders
}()
// Available returns a sorted list of available collectors.
//
+213
View File
@@ -0,0 +1,213 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package collector
import (
"maps"
"path/filepath"
"reflect"
"slices"
"strings"
"testing"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/collector/ad"
"github.com/prometheus-community/windows_exporter/internal/collector/adcs"
"github.com/prometheus-community/windows_exporter/internal/collector/adfs"
"github.com/prometheus-community/windows_exporter/internal/collector/cache"
"github.com/prometheus-community/windows_exporter/internal/collector/container"
"github.com/prometheus-community/windows_exporter/internal/collector/cpu"
"github.com/prometheus-community/windows_exporter/internal/collector/cpu_info"
"github.com/prometheus-community/windows_exporter/internal/collector/dfsr"
"github.com/prometheus-community/windows_exporter/internal/collector/dhcp"
"github.com/prometheus-community/windows_exporter/internal/collector/diskdrive"
"github.com/prometheus-community/windows_exporter/internal/collector/dmi"
"github.com/prometheus-community/windows_exporter/internal/collector/dns"
"github.com/prometheus-community/windows_exporter/internal/collector/exchange"
"github.com/prometheus-community/windows_exporter/internal/collector/file"
"github.com/prometheus-community/windows_exporter/internal/collector/fsrmquota"
"github.com/prometheus-community/windows_exporter/internal/collector/gpu"
"github.com/prometheus-community/windows_exporter/internal/collector/hyperv"
"github.com/prometheus-community/windows_exporter/internal/collector/iis"
"github.com/prometheus-community/windows_exporter/internal/collector/license"
"github.com/prometheus-community/windows_exporter/internal/collector/logical_disk"
"github.com/prometheus-community/windows_exporter/internal/collector/memory"
"github.com/prometheus-community/windows_exporter/internal/collector/mscluster"
"github.com/prometheus-community/windows_exporter/internal/collector/msmq"
"github.com/prometheus-community/windows_exporter/internal/collector/mssql"
"github.com/prometheus-community/windows_exporter/internal/collector/net"
"github.com/prometheus-community/windows_exporter/internal/collector/netframework"
"github.com/prometheus-community/windows_exporter/internal/collector/nps"
"github.com/prometheus-community/windows_exporter/internal/collector/os"
"github.com/prometheus-community/windows_exporter/internal/collector/pagefile"
"github.com/prometheus-community/windows_exporter/internal/collector/performancecounter"
"github.com/prometheus-community/windows_exporter/internal/collector/physical_disk"
"github.com/prometheus-community/windows_exporter/internal/collector/printer"
"github.com/prometheus-community/windows_exporter/internal/collector/process"
"github.com/prometheus-community/windows_exporter/internal/collector/registry"
"github.com/prometheus-community/windows_exporter/internal/collector/remote_fx"
"github.com/prometheus-community/windows_exporter/internal/collector/scheduled_task"
"github.com/prometheus-community/windows_exporter/internal/collector/service"
"github.com/prometheus-community/windows_exporter/internal/collector/smb"
"github.com/prometheus-community/windows_exporter/internal/collector/smbclient"
"github.com/prometheus-community/windows_exporter/internal/collector/smtp"
"github.com/prometheus-community/windows_exporter/internal/collector/storage_spaces"
"github.com/prometheus-community/windows_exporter/internal/collector/system"
"github.com/prometheus-community/windows_exporter/internal/collector/tcp"
"github.com/prometheus-community/windows_exporter/internal/collector/terminal_services"
"github.com/prometheus-community/windows_exporter/internal/collector/textfile"
"github.com/prometheus-community/windows_exporter/internal/collector/time"
"github.com/prometheus-community/windows_exporter/internal/collector/udp"
"github.com/prometheus-community/windows_exporter/internal/collector/update"
"github.com/prometheus-community/windows_exporter/internal/collector/vmware"
"github.com/prometheus-community/windows_exporter/internal/collector/wmi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestRegistrations verifies that every place that lists the collectors agrees
// with the registrations: the flag builders, NewWithConfig, the fields and
// YAML keys of Config, ConfigDefaults and the collector documentation.
func TestRegistrations(t *testing.T) {
t.Parallel()
names := make([]string, 0, len(registrations))
for _, r := range registrations {
require.NotContains(t, names, r.name, "collector %s is registered twice", r.name)
names = append(names, r.name)
}
slices.Sort(names)
t.Run("flag builders", func(t *testing.T) {
t.Parallel()
require.Equal(t, names, Available())
app := kingpin.New("test", "test")
for name, builder := range BuildersWithFlags {
assert.Equal(t, name, builder(app).GetName(), "flag builder of collector %s", name)
}
})
t.Run("NewWithConfig", func(t *testing.T) {
t.Parallel()
collection := NewWithConfig(ConfigDefaults)
require.Equal(t, names, slices.Sorted(maps.Keys(collection.collectors)))
for name, c := range collection.collectors {
assert.Equal(t, name, c.GetName(), "NewWithConfig collector %s", name)
}
})
t.Run("Config fields", func(t *testing.T) {
t.Parallel()
var config Config
value := reflect.ValueOf(&config).Elem()
// Fields of size zero can share an address, so the type is part of
// the key. Every collector has its own configuration type.
type fieldKey struct {
addr uintptr
typ reflect.Type
}
keyOf := func(ptr reflect.Value) fieldKey {
return fieldKey{addr: ptr.Pointer(), typ: ptr.Type().Elem()}
}
fields := map[fieldKey]reflect.StructField{}
for i := range value.NumField() {
fields[keyOf(value.Field(i).Addr())] = value.Type().Field(i)
}
for _, r := range registrations {
key := keyOf(reflect.ValueOf(r.field(&config)))
field, ok := fields[key]
if !assert.True(t, ok, "collector %s has no field in Config", r.name) {
continue
}
configKey, _, _ := strings.Cut(field.Tag.Get("yaml"), ",")
assert.Equal(t, r.name, configKey, "YAML key of Config.%s", field.Name)
delete(fields, key)
}
for _, field := range fields {
assert.Fail(t, "Config field without collector registration", "Config.%s", field.Name)
}
})
t.Run("ConfigDefaults", func(t *testing.T) {
t.Parallel()
// The defaults of every collector, listed independently of the
// registrations.
defaults := map[string]any{
ad.Name: ad.ConfigDefaults, adcs.Name: adcs.ConfigDefaults, adfs.Name: adfs.ConfigDefaults,
cache.Name: cache.ConfigDefaults, container.Name: container.ConfigDefaults, cpu.Name: cpu.ConfigDefaults,
cpu_info.Name: cpu_info.ConfigDefaults, dfsr.Name: dfsr.ConfigDefaults, dhcp.Name: dhcp.ConfigDefaults,
diskdrive.Name: diskdrive.ConfigDefaults, dmi.Name: dmi.ConfigDefaults, dns.Name: dns.ConfigDefaults,
exchange.Name: exchange.ConfigDefaults, file.Name: file.ConfigDefaults, fsrmquota.Name: fsrmquota.ConfigDefaults,
gpu.Name: gpu.ConfigDefaults, hyperv.Name: hyperv.ConfigDefaults, iis.Name: iis.ConfigDefaults,
license.Name: license.ConfigDefaults, logical_disk.Name: logical_disk.ConfigDefaults, memory.Name: memory.ConfigDefaults,
mscluster.Name: mscluster.ConfigDefaults, msmq.Name: msmq.ConfigDefaults, mssql.Name: mssql.ConfigDefaults,
net.Name: net.ConfigDefaults, netframework.Name: netframework.ConfigDefaults, nps.Name: nps.ConfigDefaults,
os.Name: os.ConfigDefaults, pagefile.Name: pagefile.ConfigDefaults, performancecounter.Name: performancecounter.ConfigDefaults,
physical_disk.Name: physical_disk.ConfigDefaults, printer.Name: printer.ConfigDefaults, process.Name: process.ConfigDefaults,
registry.Name: registry.ConfigDefaults, remote_fx.Name: remote_fx.ConfigDefaults, scheduled_task.Name: scheduled_task.ConfigDefaults,
service.Name: service.ConfigDefaults, smb.Name: smb.ConfigDefaults, smbclient.Name: smbclient.ConfigDefaults,
smtp.Name: smtp.ConfigDefaults, storage_spaces.Name: storage_spaces.ConfigDefaults, system.Name: system.ConfigDefaults,
tcp.Name: tcp.ConfigDefaults, terminal_services.Name: terminal_services.ConfigDefaults, textfile.Name: textfile.ConfigDefaults,
time.Name: time.ConfigDefaults, udp.Name: udp.ConfigDefaults, update.Name: update.ConfigDefaults,
vmware.Name: vmware.ConfigDefaults, wmi.Name: wmi.ConfigDefaults,
}
require.Len(t, defaults, len(registrations))
for _, r := range registrations {
want, ok := defaults[r.name]
if !assert.True(t, ok, "collector %s has no defaults in the test", r.name) {
continue
}
got := reflect.ValueOf(r.field(&ConfigDefaults)).Elem().Interface()
assert.Equal(t, want, got, "ConfigDefaults of collector %s", r.name)
}
})
t.Run("documentation", func(t *testing.T) {
t.Parallel()
files, err := filepath.Glob(filepath.Join("..", "..", "docs", "collector.*.md"))
require.NoError(t, err)
documented := make([]string, 0, len(files))
for _, file := range files {
documented = append(documented, strings.TrimSuffix(strings.TrimPrefix(filepath.Base(file), "collector."), ".md"))
}
require.ElementsMatch(t, names, documented, "docs/collector.<name>.md files")
})
}