chore: enable more linter (#1557)

This commit is contained in:
Jan-Otto Kröpke 2024-08-10 22:05:33 +02:00 committed by GitHub
parent 27a3553dac
commit 9b02e4a0ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
87 changed files with 337 additions and 494 deletions

View File

@ -4,79 +4,49 @@ linters:
- containedctx
- contextcheck
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exportloopref
- fatcontext
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gofumpt
- goimports
- gomoddirectives
- gomodguard
- gosimple
- gosmopolitan
- grouper
- importas
- inamedparam
- interfacebloat
- intrange
- ireturn
- lll
- maintidx
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
- nlreturn
- noctx
- nonamedreturns
- nosprintfhostport
- paralleltest
- predeclared
- protogetter
- reassign
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- tenv
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- varnamelen
- wrapcheck
- wsl
- execinquery
- gomnd
- stylecheck
- maintidx
linters-settings:
gci:
sections:
- prefix(github.com/prometheus-community/windows_exporter/pkg/initiate)
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
custom-order: true
tagliatelle:
case:
use-field-name: true
rules:
# Any struct tag type can be used.
# Support string case: `camel`, `pascal`, `kebab`, `snake`, `upperSnake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`, `header`
json: camel
yaml: snake
issues:
exclude:

View File

@ -4,7 +4,12 @@
package main
//goland:noinspection GoUnsortedImport
//nolint:gofumpt
import (
// Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts.
"github.com/prometheus-community/windows_exporter/pkg/initiate"
"context"
"encoding/json"
"fmt"
@ -22,8 +27,6 @@ import (
"github.com/go-kit/log/level"
"github.com/prometheus-community/windows_exporter/pkg/collector"
"github.com/prometheus-community/windows_exporter/pkg/config"
// Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts
"github.com/prometheus-community/windows_exporter/pkg/initiate"
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
"github.com/prometheus-community/windows_exporter/pkg/log/flag"
"github.com/prometheus-community/windows_exporter/pkg/types"
@ -39,7 +42,7 @@ import (
const PROCESS_ALL_ACCESS = windows.STANDARD_RIGHTS_REQUIRED | windows.SYNCHRONIZE | windows.SPECIFIC_RIGHTS_ALL
// Same struct prometheus uses for their /version endpoint.
// Separate copy to avoid pulling all of prometheus as a dependency
// Separate copy to avoid pulling all of prometheus as a dependency.
type prometheusVersion struct {
Version string `json:"version"`
Revision string `json:"revision"`
@ -49,7 +52,7 @@ type prometheusVersion struct {
GoVersion string `json:"goVersion"`
}
// Mapping of priority names to uin32 values required by windows.SetPriorityClass
// Mapping of priority names to uin32 values required by windows.SetPriorityClass.
var priorityStringToInt = map[string]uint32{
"realtime": windows.REALTIME_PRIORITY_CLASS,
"high": windows.HIGH_PRIORITY_CLASS,

View File

@ -19,7 +19,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DirectoryServices_DirectoryServices metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DirectoryServices_DirectoryServices metrics.
type Collector struct {
logger log.Logger

View File

@ -18,7 +18,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for Perflib Cache metrics
// A Collector is a Prometheus Collector for Perflib Cache metrics.
type Collector struct {
logger log.Logger
@ -258,7 +258,7 @@ func (c *Collector) Build() error {
return nil
}
// Collect implements the Collector interface
// Collect implements the Collector interface.
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
if err := c.collect(ctx, ch); err != nil {
_ = level.Error(c.logger).Log("msg", "failed collecting cache metrics", "err", err)

View File

@ -69,7 +69,7 @@ import (
"github.com/prometheus-community/windows_exporter/pkg/types"
)
// 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.
func NewWithFlags(app *kingpin.Application) Collectors {
collectors := map[string]Collector{}
@ -195,7 +195,7 @@ func (c *Collectors) SetPerfCounterQuery() error {
return nil
}
// Enable removes all collectors that not enabledCollectors
// Enable removes all collectors that not enabledCollectors.
func (c *Collectors) Enable(enabledCollectors []string) {
for name := range c.collectors {
if !slices.Contains(enabledCollectors, name) {
@ -204,7 +204,7 @@ func (c *Collectors) Enable(enabledCollectors []string) {
}
}
// Build To be called by the exporter for collector initialization
// Build To be called by the exporter for collector initialization.
func (c *Collectors) Build() error {
var err error
@ -217,7 +217,7 @@ func (c *Collectors) Build() error {
return nil
}
// PrepareScrapeContext creates a ScrapeContext to be used during a single scrape
// PrepareScrapeContext creates a ScrapeContext to be used during a single scrape.
func (c *Collectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
objs, err := perflib.GetPerflibSnapshot(c.perfCounterQuery)
if err != nil {
@ -227,7 +227,7 @@ func (c *Collectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
return &types.ScrapeContext{PerfObjects: objs}, nil
}
// Close To be called by the exporter for collector cleanup
// Close To be called by the exporter for collector cleanup.
func (c *Collectors) Close() error {
errs := make([]error, 0, len(c.collectors))

View File

@ -70,7 +70,7 @@ type Config struct {
Cs cs.Config `yaml:"cs"`
DFSR dfsr.Config `yaml:"dfsr"`
Dhcp dhcp.Config `yaml:"dhcp"`
DiskDrive diskdrive.Config `yaml:"diskdrive"`
DiskDrive diskdrive.Config `yaml:"diskdrive"` //nolint:tagliatelle
DNS dns.Config `yaml:"dns"`
Exchange exchange.Config `yaml:"exchange"`
Fsrmquota fsrmquota.Config `yaml:"fsrmquota"`
@ -84,7 +84,7 @@ type Config struct {
MsclusterNetwork mscluster_network.Config `yaml:"mscluster_network"`
MsclusterNode mscluster_node.Config `yaml:"mscluster_node"`
MsclusterResource mscluster_resource.Config `yaml:"mscluster_resource"`
MsclusterResourceGroup mscluster_resourcegroup.Config `yaml:"mscluster_resourcegroup"`
MsclusterResourceGroup mscluster_resourcegroup.Config `yaml:"mscluster_resourcegroup"` //nolint:tagliatelle
Msmq msmq.Config `yaml:"msmq"`
Mssql mssql.Config `yaml:"mssql"`
Net net.Config `yaml:"net"`
@ -105,7 +105,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:"smbclient"`
SMBClient smbclient.Config `yaml:"smbclient"` //nolint:tagliatelle
SMTP smtp.Config `yaml:"smtp"`
System system.Config `yaml:"system"`
TeradiciPcoip teradici_pcoip.Config `yaml:"teradici_pcoip"`

View File

@ -20,7 +20,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for containers metrics
// A Collector is a Prometheus Collector for containers metrics.
type Collector struct {
logger log.Logger
@ -55,7 +55,7 @@ type Collector struct {
writeSizeBytes *prometheus.Desc
}
// New constructs a new Collector
// New constructs a new Collector.
func New(logger log.Logger, _ *Config) *Collector {
c := &Collector{}
c.SetLogger(logger)
@ -205,7 +205,7 @@ func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
return nil
}
// containerClose closes the container resource
// containerClose closes the container resource.
func (c *Collector) containerClose(container hcsshim.Container) {
err := container.Close()
if err != nil {

View File

@ -25,7 +25,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_Processor
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_Processor.
type Collector struct {
logger log.Logger
@ -62,7 +62,7 @@ func (c *Collector) Close() error {
func (c *Collector) Build() error {
c.cpuInfo = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, "", Name),
"Labelled CPU information as provided provided by Win32_Processor",
"Labelled CPU information as provided by Win32_Processor",
[]string{
"architecture",
"device_id",

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI metrics
// A Collector is a Prometheus Collector for WMI metrics.
type Collector struct {
logger log.Logger

View File

@ -82,7 +82,7 @@ type Collector struct {
type dfsrCollectorFunc func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error
// Map Perflib sources to DFSR Collector names
// e.g, volume -> DFS Replication Service Volumes
// e.g, volume -> DFS Replication Service Volumes.
func dfsrGetPerfObjectName(collector string) string {
prefix := "DFS "
suffix := ""
@ -113,7 +113,7 @@ func New(logger log.Logger, config *Config) *Collector {
func NewWithFlags(app *kingpin.Application) *Collector {
return &Collector{
dfsrEnabledCollectors: app.
Flag("collectors.dfsr.sources-enabled", "Comma-seperated list of DFSR Perflib sources to use.").
Flag("collectors.dfsr.sources-enabled", "Comma-separated list of DFSR Perflib sources to use.").
Default(ConfigDefaults.EnabledCollectors).
String(),
}
@ -441,7 +441,7 @@ func (c *Collector) Build() error {
}
// Maps enabled child collectors names to their relevant collection function,
// for use in Collector.Collect()
// for use in Collector.Collect().
func (c *Collector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCollectorFunc {
var dfsrCollectors []dfsrCollectorFunc
for _, collector := range enabledCollectors {
@ -470,7 +470,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
return nil
}
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections"
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections".
type PerflibDFSRConnection struct {
Name string
@ -558,7 +558,7 @@ func (c *Collector) collectConnection(ctx *types.ScrapeContext, ch chan<- promet
return nil
}
// perflibDFSRFolder Perflib: "DFS Replicated Folder"
// perflibDFSRFolder Perflib: "DFS Replicated Folder".
type perflibDFSRFolder struct {
Name string
@ -790,7 +790,7 @@ func (c *Collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus
return nil
}
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes"
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes".
type perflibDFSRVolume struct {
Name string

View File

@ -16,7 +16,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector perflib DHCP metrics
// A Collector is a Prometheus Collector perflib DHCP metrics.
type Collector struct {
logger log.Logger

View File

@ -23,7 +23,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive.
type Collector struct {
logger log.Logger
@ -177,10 +177,10 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
c.diskInfo,
prometheus.GaugeValue,
1.0,
strings.Trim(disk.DeviceID, "\\.\\"),
strings.Trim(disk.DeviceID, "\\.\\"), //nolint:staticcheck
strings.TrimRight(disk.Model, " "),
strings.TrimRight(disk.Caption, " "),
strings.TrimRight(disk.Name, "\\.\\"),
strings.TrimRight(disk.Name, "\\.\\"), //nolint:staticcheck
)
for _, status := range allDiskStatus {
@ -193,7 +193,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
c.status,
prometheus.GaugeValue,
isCurrentState,
strings.Trim(disk.Name, "\\.\\"),
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
status,
)
}
@ -202,14 +202,14 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
c.size,
prometheus.GaugeValue,
float64(disk.Size),
strings.Trim(disk.Name, "\\.\\"),
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
)
ch <- prometheus.MustNewConstMetric(
c.partitions,
prometheus.GaugeValue,
float64(disk.Partitions),
strings.Trim(disk.Name, "\\.\\"),
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
)
for availNum, val := range availMap {
@ -221,7 +221,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
c.availability,
prometheus.GaugeValue,
isCurrentState,
strings.Trim(disk.Name, "\\.\\"),
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
val,
)
}

View File

@ -19,7 +19,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
type Collector struct {
logger log.Logger

View File

@ -75,7 +75,7 @@ type Collector struct {
enabledCollectors []string
}
// All available Collector functions
// All available Collector functions.
var exchangeAllCollectorNames = []string{
"ADAccessProcesses",
"TransportQueues",
@ -189,7 +189,7 @@ func (c *Collector) Build() error {
c.yieldedTasks = desc("workload_yielded_tasks", "The total number of tasks that have been yielded by a workload", "name")
c.isActive = desc("workload_is_active", "Active indicates whether the workload is in an active (1) or paused (0) state", "name")
c.activeSyncRequestsPerSec = desc("activesync_requests_total", "Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load")
c.averageCASProcessingLatency = desc("http_proxy_avg_cas_proccessing_latency_sec", "Average latency (sec) of CAS processing time over the last 200 reqs", "name")
c.averageCASProcessingLatency = desc("http_proxy_avg_cas_processing_latency_sec", "Average latency (sec) of CAS processing time over the last 200 reqs", "name")
c.mailboxServerProxyFailureRate = desc("http_proxy_mailbox_proxy_failure_rate", "% of failures between this CAS and MBX servers over the last 200 samples", "name")
c.pingCommandsPending = desc("activesync_ping_cmds_pending", "Number of ping commands currently pending in the queue")
c.syncCommandsPerSec = desc("activesync_sync_cmds_total", "Number of sync commands processed per second. Clients use this command to synchronize items within a folder")
@ -220,9 +220,7 @@ func (c *Collector) Build() error {
}
if utils.IsEmpty(c.exchangeCollectorsEnabled) {
for _, collectorName := range exchangeAllCollectorNames {
c.enabledCollectors = append(c.enabledCollectors, collectorName)
}
c.enabledCollectors = append(c.enabledCollectors, exchangeAllCollectorNames...)
} else {
for _, collectorName := range strings.Split(*c.exchangeCollectorsEnabled, ",") {
if slices.Contains(exchangeAllCollectorNames, collectorName) {
@ -236,7 +234,7 @@ func (c *Collector) Build() error {
return nil
}
// Collect collects exchange metrics and sends them to prometheus
// Collect collects exchange metrics and sends them to prometheus.
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
"ADAccessProcesses": c.collectADAccessProcesses,
@ -260,7 +258,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
return nil
}
// Perflib: [19108] MSExchange ADAccess Processes
// Perflib: [19108] MSExchange ADAccess Processes.
type perflibADAccessProcesses struct {
Name string
@ -324,7 +322,7 @@ func (c *Collector) collectADAccessProcesses(ctx *types.ScrapeContext, ch chan<-
return nil
}
// Perflib: [24914] MSExchange Availability Service
// Perflib: [24914] MSExchange Availability Service.
type perflibAvailabilityService struct {
RequestsSec float64 `perflib:"Availability Requests (sec)"`
}
@ -345,7 +343,7 @@ func (c *Collector) collectAvailabilityService(ctx *types.ScrapeContext, ch chan
return nil
}
// Perflib: [36934] MSExchange HttpProxy
// Perflib: [36934] MSExchange HttpProxy.
type perflibHTTPProxy struct {
Name string
@ -405,7 +403,7 @@ func (c *Collector) collectHTTPProxy(ctx *types.ScrapeContext, ch chan<- prometh
return nil
}
// Perflib: [24618] MSExchange OWA
// Perflib: [24618] MSExchange OWA.
type perflibOWA struct {
CurrentUniqueUsers float64 `perflib:"Current Unique Users"`
RequestsPerSec float64 `perflib:"Requests/sec"`
@ -432,7 +430,7 @@ func (c *Collector) collectOWA(ctx *types.ScrapeContext, ch chan<- prometheus.Me
return nil
}
// Perflib: [25138] MSExchange ActiveSync
// Perflib: [25138] MSExchange ActiveSync.
type perflibActiveSync struct {
RequestsPerSec float64 `perflib:"Requests/sec"`
PingCommandsPending float64 `perflib:"Ping Commands Pending"`
@ -465,7 +463,7 @@ func (c *Collector) collectActiveSync(ctx *types.ScrapeContext, ch chan<- promet
return nil
}
// Perflib: [29366] MSExchange RpcClientAccess
// Perflib: [29366] MSExchange RpcClientAccess.
type perflibRPCClientAccess struct {
RPCAveragedLatency float64 `perflib:"RPC Averaged Latency"`
RPCRequests float64 `perflib:"RPC Requests"`
@ -517,7 +515,7 @@ func (c *Collector) collectRPC(ctx *types.ScrapeContext, ch chan<- prometheus.Me
return nil
}
// Perflib: [20524] MSExchangeTransport Queues
// Perflib: [20524] MSExchangeTransport Queues.
type perflibTransportQueues struct {
Name string
@ -594,7 +592,7 @@ func (c *Collector) collectTransportQueues(ctx *types.ScrapeContext, ch chan<- p
return nil
}
// Perflib: [19430] MSExchange WorkloadManagement Workloads
// Perflib: [19430] MSExchange WorkloadManagement Workloads.
type perflibWorkloadManagementWorkloads struct {
Name string
@ -651,7 +649,7 @@ func (c *Collector) collectWorkloadManagementWorkloads(ctx *types.ScrapeContext,
return nil
}
// [29240] MSExchangeAutodiscover
// [29240] MSExchangeAutodiscover.
type perflibAutodiscover struct {
RequestsPerSec float64 `perflib:"Requests/sec"`
}
@ -671,7 +669,7 @@ func (c *Collector) collectAutoDiscover(ctx *types.ScrapeContext, ch chan<- prom
return nil
}
// perflib [26463] MSExchange MapiHttp Emsmdb
// perflib [26463] MSExchange MapiHttp Emsmdb.
type perflibMapiHttpEmsmdb struct {
ActiveUserCount float64 `perflib:"Active User Count"`
}
@ -693,14 +691,14 @@ func (c *Collector) collectMapiHttpEmsmdb(ctx *types.ScrapeContext, ch chan<- pr
return nil
}
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores.
func (c *Collector) toLabelName(name string) string {
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
s = strings.ReplaceAll(s, "__", "_")
return s
}
// msToSec converts from ms to seconds
// msToSec converts from ms to seconds.
func (c *Collector) msToSec(t float64) float64 {
return t / 1000
}

View File

@ -55,7 +55,7 @@ func (c *Collectors) BuildServeHTTP(disableExporterMetrics bool, timeoutMargin f
if timeoutSeconds == 0 {
timeoutSeconds = defaultTimeout
}
timeoutSeconds = timeoutSeconds - timeoutMargin
timeoutSeconds -= timeoutMargin
reg := prometheus.NewRegistry()
err, wc := collectorFactory(time.Duration(timeoutSeconds*float64(time.Second)), r.URL.Query()["collect[]"])

View File

@ -20,7 +20,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// Collector is a Prometheus Collector for hyper-v
// Collector is a Prometheus Collector for hyper-v.
type Collector struct {
logger log.Logger
@ -810,7 +810,7 @@ func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
return nil
}
// Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary vm health status
// Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary vm health status.
type Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary struct {
HealthCritical uint32
HealthOk uint32
@ -840,7 +840,7 @@ func (c *Collector) collectVmHealth(ch chan<- prometheus.Metric) error {
return nil
}
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition ..,
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition ..,.
type Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition struct {
Name string
PhysicalPagesAllocated uint64

View File

@ -987,22 +987,22 @@ type perflibWebService struct {
TotalUnlockRequests float64 `perflib:"Total Unlock Requests"`
}
// Fulfill the hasGetIISName interface
// Fulfill the hasGetIISName interface.
func (p perflibWebService) getIISName() string {
return p.Name
}
// Fulfill the hasGetIISName interface
// Fulfill the hasGetIISName interface.
func (p perflibAPP_POOL_WAS) getIISName() string {
return p.Name
}
// Fulfill the hasGetIISName interface
// Fulfill the hasGetIISName interface.
func (p perflibW3SVC_W3WP) getIISName() string {
return p.Name
}
// Fulfill the hasGetIISName interface
// Fulfill the hasGetIISName interface.
func (p perflibW3SVC_W3WP_IIS8) getIISName() string {
return p.Name
}
@ -1017,7 +1017,7 @@ type hasGetIISName interface {
// E.G. Given the following list of site names, "Site_B" would be
// discarded, and "Site_B#2" would be kept and presented as "Site_B" in the
// Collector metrics.
// [ "Site_A", "Site_B", "Site_C", "Site_B#2" ]
// [ "Site_A", "Site_B", "Site_C", "Site_B#2" ].
func dedupIISNames[V hasGetIISName](services []V) map[string]V {
// Ensure IIS entry with the highest suffix occurs last
sort.SliceStable(services, func(i, j int) bool {
@ -1457,13 +1457,13 @@ type perflibW3SVC_W3WP struct {
URICacheFlushesTotal float64 `perflib:"Total Flushed URIs"`
URICacheFlushesTotalKernel float64 `perflib:"Total Flushed URIs"`
URIsFlushedTotalKernel float64 `perflib:"Kernel\: Total Flushed URIs"` //nolint:govet
URIsFlushedTotalKernel float64 `perflib:"Kernel\: Total Flushed URIs"` //nolint:govet,tagalign,staticcheck
URICacheHitsTotal float64 `perflib:"URI Cache Hits"`
URICacheHitsTotalKernel float64 `perflib:"Kernel\: URI Cache Hits"` //nolint:govet
URICacheHitsTotalKernel float64 `perflib:"Kernel\: URI Cache Hits"` //nolint:govet,tagalign,staticcheck
URICacheMissesTotal float64 `perflib:"URI Cache Misses"`
URICacheMissesTotalKernel float64 `perflib:"Kernel\: URI Cache Misses"` //nolint:govet
URICacheMissesTotalKernel float64 `perflib:"Kernel\: URI Cache Misses"` //nolint:govet,tagalign,staticcheck
URIsCached float64 `perflib:"Current URIs Cached"`
URIsCachedKernel float64 `perflib:"Kernel\: Current URIs Cached"` //nolint:govet
URIsCachedKernel float64 `perflib:"Kernel\: Current URIs Cached"` //nolint:govet,tagalign,staticcheck
URIsCachedTotal float64 `perflib:"Total URIs Cached"`
URIsCachedTotalKernel float64 `perflib:"Total URIs Cached"`
URIsFlushedTotal float64 `perflib:"Total Flushed URIs"`

View File

@ -6,6 +6,8 @@ import (
)
func TestIISDeduplication(t *testing.T) {
t.Parallel()
start := []perflibAPP_POOL_WAS{
{
Name: "foo",

View File

@ -25,7 +25,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
type Collector struct {
logger log.Logger

View File

@ -31,7 +31,7 @@ var ConfigDefaults = Config{
VolumeExclude: "",
}
// A Collector is a Prometheus Collector for perflib logicalDisk metrics
// A Collector is a Prometheus Collector for perflib logicalDisk metrics.
type Collector struct {
logger log.Logger
@ -264,7 +264,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
// Win32_PerfRawData_PerfDisk_LogicalDisk docs:
// - https://msdn.microsoft.com/en-us/windows/hardware/aa394307(v=vs.71) - Win32_PerfRawData_PerfDisk_LogicalDisk class
// - https://msdn.microsoft.com/en-us/library/ms803973.aspx - LogicalDisk object reference
// - https://msdn.microsoft.com/en-us/library/ms803973.aspx - LogicalDisk object reference.
type logicalDisk struct {
Name string
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
@ -478,7 +478,6 @@ func getDiskIDByVolume(rootDrive string) (string, error) {
f, err = windows.CreateFile(
windows.StringToUTF16Ptr(`\\.\`+rootDrive),
0, mode, nil, windows.OPEN_EXISTING, uint32(windows.FILE_ATTRIBUTE_READONLY), 0)
if err != nil {
return "", err
}
@ -527,7 +526,6 @@ func getVolumeInfo(rootDrive string) (volumeInfo, error) {
err := windows.GetVolumeInformation(volPath, &volBufLabel[0], uint32(len(volBufLabel)),
&volSerialNum, nil, &fsFlags, &volBufType[0], uint32(len(volBufType)))
if err != nil {
if driveType != windows.DRIVE_CDROM && driveType != windows.DRIVE_REMOVABLE {
return volumeInfo{}, err

View File

@ -19,7 +19,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI metrics
// A Collector is a Prometheus Collector for WMI metrics.
type Collector struct {
logger log.Logger

View File

@ -20,7 +20,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for perflib Memory metrics
// A Collector is a Prometheus Collector for perflib Memory metrics.
type Collector struct {
logger log.Logger

View File

@ -14,7 +14,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI MSCluster_Cluster metrics
// A Collector is a Prometheus Collector for WMI MSCluster_Cluster metrics.
type Collector struct {
logger log.Logger

View File

@ -14,7 +14,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI MSCluster_Network metrics
// A Collector is a Prometheus Collector for WMI MSCluster_Network metrics.
type Collector struct {
logger log.Logger

View File

@ -14,10 +14,10 @@ type Config struct{}
var ConfigDefaults = Config{}
// Variable used by mscluster_resource and mscluster_resourcegroup
// Variable used by mscluster_resource and mscluster_resourcegroup.
var NodeName []string
// A Collector is a Prometheus Collector for WMI MSCluster_Node metrics
// A Collector is a Prometheus Collector for WMI MSCluster_Node metrics.
type Collector struct {
logger log.Logger

View File

@ -15,7 +15,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI MSCluster_Resource metrics
// A Collector is a Prometheus Collector for WMI MSCluster_Resource metrics.
type Collector struct {
logger log.Logger

View File

@ -15,7 +15,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI MSCluster_ResourceGroup metrics
// A Collector is a Prometheus Collector for WMI MSCluster_ResourceGroup metrics.
type Collector struct {
logger log.Logger

View File

@ -24,7 +24,7 @@ var ConfigDefaults = Config{
QueryWhereClause: "",
}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics.
type Collector struct {
logger log.Logger

View File

@ -23,7 +23,7 @@ import (
const Name = "mssql"
type Config struct {
EnabledCollectors string `yaml:"collectors_enabled"`
EnabledCollectors string `yaml:"collectors_enabled"` //nolint:tagliatelle
}
var ConfigDefaults = Config{
@ -126,7 +126,7 @@ func mssqlGetPerfObjectName(sqlInstance string, collector string) string {
return prefix + suffix
}
// A Collector is a Prometheus Collector for various WMI Win32_PerfRawData_MSSQLSERVER_* metrics
// A Collector is a Prometheus Collector for various WMI Win32_PerfRawData_MSSQLSERVER_* metrics.
type Collector struct {
logger log.Logger

View File

@ -28,7 +28,7 @@ var ConfigDefaults = Config{
var nicNameToUnderscore = regexp.MustCompile("[^a-zA-Z0-9]")
// A Collector is a Prometheus Collector for Perflib Network Interface metrics
// A Collector is a Prometheus Collector for Perflib Network Interface metrics.
type Collector struct {
logger log.Logger

View File

@ -7,6 +7,8 @@ import (
)
func TestNetworkToInstanceName(t *testing.T) {
t.Parallel()
data := map[string]string{
"Intel[R] Dual Band Wireless-AC 8260": "Intel_R__Dual_Band_Wireless_AC_8260",
}

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRExceptions metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRExceptions metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRInterop metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRInterop metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRJit metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRJit metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRLoading metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRLoading metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRMemory metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRMemory metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRRemoting metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRRemoting metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRSecurity metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_NETFramework_NETCLRSecurity metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// Collector is a Prometheus Collector for WMI Win32_PerfRawData_IAS_NPSAuthenticationServer and Win32_PerfRawData_IAS_NPSAccountingServer metrics
// Collector is a Prometheus Collector for WMI Win32_PerfRawData_IAS_NPSAuthenticationServer and Win32_PerfRawData_IAS_NPSAccountingServer metrics.
type Collector struct {
logger log.Logger
@ -246,7 +246,7 @@ func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
}
// Win32_PerfRawData_IAS_NPSAuthenticationServer docs:
// at the moment there is no Microsoft documentation
// at the moment there is no Microsoft documentation.
type Win32_PerfRawData_IAS_NPSAuthenticationServer struct {
Name string

View File

@ -30,7 +30,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI metrics
// A Collector is a Prometheus Collector for WMI metrics.
type Collector struct {
logger log.Logger
@ -175,7 +175,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
}
// Win32_OperatingSystem docs:
// - https://msdn.microsoft.com/en-us/library/aa394239 - Win32_OperatingSystem class
// - https://msdn.microsoft.com/en-us/library/aa394239 - Win32_OperatingSystem class.
type Win32_OperatingSystem struct {
Caption string
FreePhysicalMemory uint64
@ -215,11 +215,12 @@ func (c *Collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
// Get total allocation of paging files across all disks.
memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE)
defer memManKey.Close()
if err != nil {
return err
}
defer memManKey.Close()
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
var fsipf float64
@ -236,12 +237,12 @@ func (c *Collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
// Get build number and product name from registry
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
defer ntKey.Close()
if err != nil {
return err
}
defer ntKey.Close()
pn, _, err := ntKey.GetStringValue("ProductName")
if err != nil {
return err

View File

@ -27,7 +27,7 @@ var ConfigDefaults = Config{
DiskExclude: "",
}
// A Collector is a Prometheus Collector for perflib PhysicalDisk metrics
// A Collector is a Prometheus Collector for perflib PhysicalDisk metrics.
type Collector struct {
logger log.Logger
@ -217,7 +217,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
// PhysicalDisk
// Win32_PerfRawData_PerfDisk_PhysicalDisk docs:
// - https://docs.microsoft.com/en-us/previous-versions/aa394308(v=vs.85) - Win32_PerfRawData_PerfDisk_PhysicalDisk class
// - https://docs.microsoft.com/en-us/previous-versions/aa394308(v=vs.85) - Win32_PerfRawData_PerfDisk_PhysicalDisk class.
type PhysicalDisk struct {
Name string
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`

View File

@ -26,7 +26,7 @@ const Name = "process"
type Config struct {
ProcessInclude string `yaml:"process_include"`
ProcessExclude string `yaml:"process_exclude"`
EnableWorkerProcess bool `yaml:"enable_iis_worker_process"`
EnableWorkerProcess bool `yaml:"enable_iis_worker_process"` //nolint:tagliatelle
EnableReportOwner bool `yaml:"enable_report_owner"`
}
@ -488,7 +488,7 @@ func (c *Collector) getProcessOwner(pid int) (string, error) {
}
if err != nil {
return "", fmt.Errorf("OpenProcess: %T %w", err, err)
return "", fmt.Errorf("OpenProcess: %w", err)
}
defer windows.Close(p)

View File

@ -87,7 +87,7 @@ func (coll *Prometheus) Collect(ch chan<- prometheus.Metric) {
time.Since(t).Seconds(),
)
if err != nil {
ch <- prometheus.NewInvalidMetric(coll.scrapeSuccessDesc, fmt.Errorf("failed to prepare scrape: %v", err))
ch <- prometheus.NewInvalidMetric(coll.scrapeSuccessDesc, fmt.Errorf("failed to prepare scrape: %w", err))
return
}

View File

@ -423,7 +423,7 @@ func (c *Collector) collectRemoteFXGraphicsCounters(ctx *types.ScrapeContext, ch
return nil
}
// normalizeSessionName ensure that the session is the same between WTS API and performance counters
// normalizeSessionName ensure that the session is the same between WTS API and performance counters.
func normalizeSessionName(sessionName string) string {
return strings.Replace(sessionName, "RDP-tcp", "RDP-Tcp", 1)
}

View File

@ -225,7 +225,9 @@ const SCHEDULED_TASK_PROGRAM_ID = "Schedule.Service.1"
// S_FALSE is returned by CoInitialize if it was already called on this thread.
const S_FALSE = 0x00000001
func getScheduledTasks() (scheduledTasks ScheduledTasks, err error) {
func getScheduledTasks() (ScheduledTasks, error) {
var scheduledTasks ScheduledTasks
// The only way to run WMI queries in parallel while being thread-safe is to
// ensure the CoInitialize[Ex]() call is bound to its current OS thread.
// Otherwise, attempting to initialize and run parallel queries across
@ -320,7 +322,9 @@ func fetchTasksRecursively(folder *ole.IDispatch, scheduledTasks *ScheduledTasks
return err
}
func parseTask(task *ole.IDispatch) (scheduledTask ScheduledTask, err error) {
func parseTask(task *ole.IDispatch) (ScheduledTask, error) {
var scheduledTask ScheduledTask
taskNameVar, err := oleutil.GetProperty(task, "Name")
if err != nil {
return scheduledTask, err

View File

@ -35,7 +35,7 @@ var ConfigDefaults = Config{
V2: false,
}
// A Collector is a Prometheus Collector for WMI Win32_Service metrics
// A Collector is a Prometheus Collector for WMI Win32_Service metrics.
type Collector struct {
logger log.Logger

View File

@ -38,7 +38,7 @@ type Collector struct {
enabledCollectors []string
}
// All available Collector functions
// All available Collector functions.
var smbAllCollectorNames = []string{
"ServerShares",
}
@ -121,9 +121,7 @@ func (c *Collector) Build() error {
}
if *c.smbCollectorsEnabled == "" {
for _, collectorName := range smbAllCollectorNames {
c.enabledCollectors = append(c.enabledCollectors, collectorName)
}
c.enabledCollectors = append(c.enabledCollectors, smbAllCollectorNames...)
} else {
for _, collectorName := range strings.Split(*c.smbCollectorsEnabled, ",") {
if slices.Contains(smbAllCollectorNames, collectorName) {
@ -137,7 +135,7 @@ func (c *Collector) Build() error {
return nil
}
// Collect collects smb metrics and sends them to prometheus
// Collect collects smb metrics and sends them to prometheus.
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
"ServerShares": c.collectServerShares,
@ -152,7 +150,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
return nil
}
// Perflib: SMB Server Shares
// Perflib: SMB Server Shares.
type perflibServerShares struct {
Name string
@ -186,7 +184,7 @@ func (c *Collector) collectServerShares(ctx *types.ScrapeContext, ch chan<- prom
return nil
}
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores.
func (c *Collector) toLabelName(name string) string {
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
s = strings.ReplaceAll(s, "__", "_")

View File

@ -60,7 +60,7 @@ type Collector struct {
requestSecs *prometheus.Desc
}
// All available collector functions
// All available collector functions.
var smbclientAllCollectorNames = []string{
"ClientShares",
}
@ -224,9 +224,7 @@ func (c *Collector) Build() error {
}
if *c.smbClientCollectorsEnabled == "" {
for _, collectorName := range smbclientAllCollectorNames {
c.enabledCollectors = append(c.enabledCollectors, collectorName)
}
c.enabledCollectors = append(c.enabledCollectors, smbclientAllCollectorNames...)
} else {
for _, collectorName := range strings.Split(*c.smbClientCollectorsEnabled, ",") {
if slices.Contains(smbclientAllCollectorNames, collectorName) {
@ -240,7 +238,7 @@ func (c *Collector) Build() error {
return nil
}
// Collect collects smb client metrics and sends them to prometheus
// Collect collects smb client metrics and sends them to prometheus.
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
"ClientShares": c.collectClientShares,
@ -255,7 +253,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
return nil
}
// Perflib: SMB Client Shares
// Perflib: SMB Client Shares.
type perflibClientShares struct {
Name string

View File

@ -405,7 +405,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
return nil
}
// PerflibSMTPServer Perflib: "SMTP Server"
// PerflibSMTPServer Perflib: "SMTP Server".
type PerflibSMTPServer struct {
Name string

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI metrics
// A Collector is a Prometheus Collector for WMI metrics.
type Collector struct {
logger log.Logger

View File

@ -17,7 +17,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_Tcpip_TCPv{4,6} metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_Tcpip_TCPv{4,6} metrics.
type Collector struct {
logger log.Logger

View File

@ -24,7 +24,7 @@ var ConfigDefaults = Config{}
// win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics
// win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics
// win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
// win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics
// win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics.
type Collector struct {
logger log.Logger

View File

@ -102,7 +102,6 @@ func (c *Collector) GetPerfCounter() ([]string, error) {
func (c *Collector) Close() error {
err := wtsapi32.WTSCloseServer(c.hServer)
if err != nil {
return fmt.Errorf("failed to close WTS server: %w", err)
}
@ -434,7 +433,7 @@ func (c *Collector) collectWTSSessions(ch chan<- prometheus.Metric) error {
c.sessionInfo,
prometheus.GaugeValue,
isState,
strings.Replace(session.SessionName, "#", " ", -1),
strings.ReplaceAll(session.SessionName, "#", " "),
userName,
session.HostName,
stateName,

View File

@ -120,21 +120,21 @@ func (c *Collector) Build() error {
func duplicateMetricEntry(metricFamilies []*dto.MetricFamily) bool {
uniqueMetrics := make(map[string]map[string]string)
for _, metricFamily := range metricFamilies {
metric_name := *metricFamily.Name
for _, metric := range metricFamily.Metric {
metric_labels := metric.GetLabel()
metricName := metricFamily.GetName()
for _, metric := range metricFamily.GetMetric() {
metricLabels := metric.GetLabel()
labels := make(map[string]string)
for _, label := range metric_labels {
for _, label := range metricLabels {
labels[label.GetName()] = label.GetValue()
}
// Check if key is present before appending
_, mapContainsKey := uniqueMetrics[metric_name]
_, mapContainsKey := uniqueMetrics[metricName]
// Duplicate metric found with identical labels & label values
if mapContainsKey == true && reflect.DeepEqual(uniqueMetrics[metric_name], labels) {
if mapContainsKey && reflect.DeepEqual(uniqueMetrics[metricName], labels) {
return true
}
uniqueMetrics[metric_name] = labels
uniqueMetrics[metricName] = labels
}
}
return false
@ -145,7 +145,7 @@ func (c *Collector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<
var val float64
allLabelNames := map[string]struct{}{}
for _, metric := range metricFamily.Metric {
for _, metric := range metricFamily.GetMetric() {
labels := metric.GetLabel()
for _, label := range labels {
if _, ok := allLabelNames[label.GetName()]; !ok {
@ -154,7 +154,7 @@ func (c *Collector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<
}
}
for _, metric := range metricFamily.Metric {
for _, metric := range metricFamily.GetMetric() {
if metric.TimestampMs != nil {
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Ignoring unsupported custom timestamp on textfile Collector metric %v", metric))
}
@ -175,7 +175,7 @@ func (c *Collector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<
break
}
}
if present == false {
if !present {
names = append(names, k)
values = append(values, "")
}
@ -185,44 +185,44 @@ func (c *Collector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<
switch metricType {
case dto.MetricType_COUNTER:
valType = prometheus.CounterValue
val = metric.Counter.GetValue()
val = metric.GetCounter().GetValue()
case dto.MetricType_GAUGE:
valType = prometheus.GaugeValue
val = metric.Gauge.GetValue()
val = metric.GetGauge().GetValue()
case dto.MetricType_UNTYPED:
valType = prometheus.UntypedValue
val = metric.Untyped.GetValue()
val = metric.GetUntyped().GetValue()
case dto.MetricType_SUMMARY:
quantiles := map[float64]float64{}
for _, q := range metric.Summary.Quantile {
for _, q := range metric.GetSummary().GetQuantile() {
quantiles[q.GetQuantile()] = q.GetValue()
}
ch <- prometheus.MustNewConstSummary(
prometheus.NewDesc(
*metricFamily.Name,
metricFamily.GetName(),
metricFamily.GetHelp(),
names, nil,
),
metric.Summary.GetSampleCount(),
metric.Summary.GetSampleSum(),
metric.GetSummary().GetSampleCount(),
metric.GetSummary().GetSampleSum(),
quantiles, values...,
)
case dto.MetricType_HISTOGRAM:
buckets := map[float64]uint64{}
for _, b := range metric.Histogram.Bucket {
for _, b := range metric.GetHistogram().GetBucket() {
buckets[b.GetUpperBound()] = b.GetCumulativeCount()
}
ch <- prometheus.MustNewConstHistogram(
prometheus.NewDesc(
*metricFamily.Name,
metricFamily.GetName(),
metricFamily.GetHelp(),
names, nil,
),
metric.Histogram.GetSampleCount(),
metric.Histogram.GetSampleSum(),
metric.GetHistogram().GetSampleCount(),
metric.GetHistogram().GetSampleSum(),
buckets, values...,
)
default:
@ -232,7 +232,7 @@ func (c *Collector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<
if metricType == dto.MetricType_GAUGE || metricType == dto.MetricType_COUNTER || metricType == dto.MetricType_UNTYPED {
ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(
*metricFamily.Name,
metricFamily.GetName(),
metricFamily.GetHelp(),
names, nil,
),
@ -266,7 +266,7 @@ type carriageReturnFilteringReader struct {
r io.Reader
}
// Read returns data from the underlying io.Reader, but with \r filtered out
// Read returns data from the underlying io.Reader, but with \r filtered out.
func (cr carriageReturnFilteringReader) Read(p []byte) (int, error) {
buf := make([]byte, len(p))
n, err := cr.r.Read(buf)
@ -276,7 +276,7 @@ func (cr carriageReturnFilteringReader) Read(p []byte) (int, error) {
}
pi := 0
for i := 0; i < n; i++ {
for i := range n {
if buf[i] != '\r' {
p[pi] = buf[i]
pi++
@ -380,7 +380,7 @@ func scrapeFile(path string, log log.Logger) ([]*dto.MetricFamily, error) {
for _, mf := range parsedFamilies {
families_array = append(families_array, mf)
for _, m := range mf.Metric {
for _, m := range mf.GetMetric() {
if m.TimestampMs != nil {
return nil, errors.New("textfile contains unsupported client-side timestamps")
}

View File

@ -10,6 +10,8 @@ import (
)
func TestCRFilter(t *testing.T) {
t.Parallel()
sr := strings.NewReader("line 1\r\nline 2")
cr := carriageReturnFilteringReader{r: sr}
b, err := io.ReadAll(cr)
@ -23,6 +25,8 @@ func TestCRFilter(t *testing.T) {
}
func TestCheckBOM(t *testing.T) {
t.Parallel()
testdata := []struct {
encoding utfbom.Encoding
err string
@ -49,6 +53,8 @@ func TestCheckBOM(t *testing.T) {
}
func TestDuplicateMetricEntry(t *testing.T) {
t.Parallel()
metric_name := "windows_sometest"
metric_help := "This is a Test."
metric_type := dto.MetricType_GAUGE

View File

@ -17,6 +17,8 @@ import (
var baseDir = "../../../tools/textfile-test"
func TestMultipleDirectories(t *testing.T) {
t.Parallel()
testDir := baseDir + "/multiple-dirs"
testDirs := fmt.Sprintf("%[1]s/dir1,%[1]s/dir2,%[1]s/dir3", testDir)
@ -58,6 +60,8 @@ func TestMultipleDirectories(t *testing.T) {
}
func TestDuplicateFileName(t *testing.T) {
t.Parallel()
testDir := baseDir + "/duplicate-filename"
textfileCollector := textfile.New(log.NewLogfmtLogger(os.Stdout), &textfile.Config{
TextFileDirectories: testDir,

View File

@ -19,7 +19,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_Counters_ThermalZoneInformation metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_Counters_ThermalZoneInformation metrics.
type Collector struct {
logger log.Logger

View File

@ -20,7 +20,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// Collector is a Prometheus Collector for Perflib counter metrics
// Collector is a Prometheus Collector for Perflib counter metrics.
type Collector struct {
logger log.Logger
@ -113,7 +113,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
return nil
}
// Perflib "Windows Time Service"
// Perflib "Windows Time Service".
type windowsTime struct {
ClockFrequencyAdjustmentPPBTotal float64 `perflib:"Clock Frequency Adjustment (ppb)"`
ComputedTimeOffset float64 `perflib:"Computed Time Offset"`

View File

@ -16,8 +16,10 @@ type Collectors struct {
type Map map[string]Collector
type Builder func(logger log.Logger) Collector
type BuilderWithFlags[C Collector] func(*kingpin.Application) C
type (
Builder func(logger log.Logger) Collector
BuilderWithFlags[C Collector] func(*kingpin.Application) C
)
// Collector interface that a collector has to implement.
type Collector interface {

View File

@ -20,7 +20,7 @@ type Config struct{}
var ConfigDefaults = Config{}
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_vmGuestLib_VMem/Win32_PerfRawData_vmGuestLib_VCPU metrics
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_vmGuestLib_VMem/Win32_PerfRawData_vmGuestLib_VCPU metrics.
type Collector struct {
logger log.Logger

View File

@ -42,39 +42,24 @@ func NewResolver(file string, logger log.Logger, insecureSkipVerify bool) (*Reso
var fileBytes []byte
var err error
if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") {
_ = level.Info(logger).Log("msg", fmt.Sprintf("Loading configuration file from URL: %v", file))
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: insecureSkipVerify}, //nolint:gosec
}
if insecureSkipVerify {
_ = level.Warn(logger).Log("msg", "Loading configuration file with TLS verification disabled")
}
client := &http.Client{Transport: tr}
resp, err := client.Get(file)
if err != nil {
return nil, err
}
defer resp.Body.Close()
fileBytes, err = io.ReadAll(resp.Body)
fileBytes, err = readFromURL(file, logger, insecureSkipVerify)
if err != nil {
return nil, err
}
} else {
_ = level.Info(logger).Log("msg", fmt.Sprintf("Loading configuration file: %v", file))
if _, err := os.Stat(file); err != nil {
return nil, err
}
fileBytes, err = os.ReadFile(file)
fileBytes, err = readFromFile(file, logger)
if err != nil {
return nil, err
}
}
var rawValues map[string]interface{}
err = yaml.Unmarshal(fileBytes, &rawValues)
if err != nil {
return nil, err
}
// Flatten nested YAML values
flattenedValues := flatten(rawValues)
for k, v := range flattenedValues {
@ -82,9 +67,51 @@ func NewResolver(file string, logger log.Logger, insecureSkipVerify bool) (*Reso
flags[k] = v
}
}
return &Resolver{flags: flags}, nil
}
func readFromFile(file string, logger log.Logger) ([]byte, error) {
_ = level.Info(logger).Log("msg", fmt.Sprintf("Loading configuration file: %v", file))
if _, err := os.Stat(file); err != nil {
return nil, err
}
fileBytes, err := os.ReadFile(file)
if err != nil {
return nil, err
}
return fileBytes, err
}
func readFromURL(file string, logger log.Logger, insecureSkipVerify bool) ([]byte, error) {
_ = level.Info(logger).Log("msg", fmt.Sprintf("Loading configuration file from URL: %v", file))
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: insecureSkipVerify}, //nolint:gosec
}
if insecureSkipVerify {
_ = level.Warn(logger).Log("msg", "Loading configuration file with TLS verification disabled")
}
client := &http.Client{Transport: tr}
resp, err := client.Get(file)
if err != nil {
return nil, err
}
defer resp.Body.Close()
fileBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return fileBytes, nil
}
func (c *Resolver) setDefault(v getFlagger) {
for name, value := range c.flags {
f := v.GetFlag(name)

View File

@ -9,7 +9,7 @@ import (
//
// All keys will be joined by dot
// e.g. {"a": {"b":"c"}} => {"a.b":"c"}
// or {"a": {"b":[1,2]}} => {"a.b.0":1, "a.b.1": 2}
// or {"a": {"b":[1,2]}} => {"a.b.0":1, "a.b.1": 2}.
func flatten(data map[string]interface{}) map[string]string {
ret := make(map[string]string)
for k, v := range data {
@ -32,6 +32,7 @@ func flatten(data map[string]interface{}) map[string]string {
}
return ret
}
func flattenSlice(data []interface{}) map[string]string {
ret := make(map[string]string)
for idx, v := range data {

View File

@ -7,8 +7,10 @@ import (
"gopkg.in/yaml.v3"
)
// Unmarshal good configuration file and confirm data is flattened correctly
// Unmarshal good configuration file and confirm data is flattened correctly.
func TestConfigFlattening(t *testing.T) {
t.Parallel()
goodYamlConfig := []byte(`---
collectors:

View File

@ -19,7 +19,7 @@ type wKSTAInfo102 struct {
wki102_logged_on_users uint32
}
// WorkstationInfo is an idiomatic wrapper of WKSTAInfo102
// WorkstationInfo is an idiomatic wrapper of WKSTAInfo102.
type WorkstationInfo struct {
PlatformId uint32
ComputerName string
@ -89,7 +89,7 @@ func netWkstaGetInfo() (wKSTAInfo102, uint32, error) {
return deref, 0, nil
}
// GetWorkstationInfo is an idiomatic wrapper for netWkstaGetInfo
// GetWorkstationInfo is an idiomatic wrapper for netWkstaGetInfo.
func GetWorkstationInfo() (WorkstationInfo, error) {
info, _, err := netWkstaGetInfo()
if err != nil {

View File

@ -24,7 +24,7 @@ const (
SL_GEN_STATE_LAST
)
// SLIsWindowsGenuineLocal function wrapper
// SLIsWindowsGenuineLocal function wrapper.
func SLIsWindowsGenuineLocal() (SL_GENUINE_STATE, error) {
var genuineState SL_GENUINE_STATE

View File

@ -21,7 +21,7 @@ type memoryStatusEx struct {
UllAvailExtendedVirtual uint64
}
// MemoryStatus is an idiomatic wrapper for MemoryStatusEx
// MemoryStatus is an idiomatic wrapper for MemoryStatusEx.
type MemoryStatus struct {
MemoryLoad uint32
TotalPhys uint64
@ -40,17 +40,17 @@ type wProcessorArchitecture struct {
WReserved uint16
}
// ProcessorArchitecture is an idiomatic wrapper for wProcessorArchitecture
// ProcessorArchitecture is an idiomatic wrapper for wProcessorArchitecture.
type ProcessorArchitecture uint16
// Idiomatic values for wProcessorArchitecture
// Idiomatic values for wProcessorArchitecture.
const (
AMD64 ProcessorArchitecture = 9
ARM = 5
ARM64 = 12
IA64 = 6
INTEL = 0
UNKNOWN = 0xffff
ARM ProcessorArchitecture = 5
ARM64 ProcessorArchitecture = 12
IA64 ProcessorArchitecture = 6
INTEL ProcessorArchitecture = 0
UNKNOWN ProcessorArchitecture = 0xffff
)
// LpSystemInfo is a wrapper for LPSYSTEM_INFO
@ -68,7 +68,7 @@ type lpSystemInfo struct {
WProcessorRevision uint16
}
// SystemInfo is an idiomatic wrapper for LpSystemInfo
// SystemInfo is an idiomatic wrapper for LpSystemInfo.
type SystemInfo struct {
Arch ProcessorArchitecture
PageSize uint32
@ -82,10 +82,10 @@ type SystemInfo struct {
ProcessorRevision uint16
}
// WinComputerNameFormat is a wrapper for COMPUTER_NAME_FORMAT
// WinComputerNameFormat is a wrapper for COMPUTER_NAME_FORMAT.
type WinComputerNameFormat int
// Definitions for WinComputerNameFormat constants
// Definitions for WinComputerNameFormat constants.
const (
ComputerNameNetBIOS WinComputerNameFormat = iota
ComputerNameDNSHostname
@ -112,7 +112,7 @@ func GlobalMemoryStatusEx() (MemoryStatus, error) {
mse.dwLength = (uint32)(unsafe.Sizeof(mse))
r1, _, err := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&mse)))
if ret := *(*bool)(unsafe.Pointer(&r1)); ret == false {
if ret := *(*bool)(unsafe.Pointer(&r1)); !ret {
return MemoryStatus{}, err
}

View File

@ -12,7 +12,7 @@ import (
type WTSTypeClass int
// The valid values for the WTSTypeClass enumeration
// The valid values for the WTSTypeClass enumeration.
const (
WTSTypeProcessInfoLevel0 WTSTypeClass = iota
WTSTypeProcessInfoLevel1
@ -138,11 +138,11 @@ func WTSCloseServer(server syscall.Handle) error {
return nil
}
func WTSFreeMemoryEx(class WTSTypeClass, pMemory uintptr, NumberOfEntries uint32) error {
func WTSFreeMemoryEx(class WTSTypeClass, pMemory uintptr, numberOfEntries uint32) error {
r1, _, err := procWTSFreeMemoryEx.Call(
uintptr(class),
pMemory,
uintptr(NumberOfEntries),
uintptr(numberOfEntries),
)
if r1 != 1 {
@ -182,7 +182,7 @@ func WTSEnumerateSessionsEx(server syscall.Handle, logger log.Logger) ([]WTSSess
sessionSize := unsafe.Sizeof(sizeTest)
sessions := make([]WTSSession, 0, count)
for i := uint32(0); i < count; i++ {
for i := range count {
curPtr := unsafe.Pointer(sessionInfoPointer + (uintptr(i) * sessionSize))
data := (*wtsSessionInfo1)(curPtr)

View File

@ -17,31 +17,32 @@ type windowsExporterService struct{}
var logger *eventlog.Log
//nolint:nonamedreturns
func (s *windowsExporterService) Execute(_ []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
changes <- svc.Status{State: svc.StartPending}
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
loop:
for {
select {
case c := <-r:
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
_ = logger.Info(100, "Service Stop Received")
changes <- svc.Status{State: svc.StopPending}
break loop
default:
_ = logger.Error(102, fmt.Sprintf("unexpected control request #%d", c))
}
for c := range r {
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
_ = logger.Info(100, "Service Stop Received")
changes <- svc.Status{State: svc.StopPending}
return
default:
_ = logger.Error(102, fmt.Sprintf("unexpected control request #%d", c))
}
}
return
}
var StopCh = make(chan bool)
//nolint:gochecknoinits
func init() {
isService, err := svc.IsWindowsService()
if err != nil {

View File

@ -70,7 +70,7 @@ func (l *eventlogLogger) Log(keyvals ...interface{}) error {
msg, err := syscall.UTF16PtrFromString(lb.buf.String())
if err != nil {
return fmt.Errorf("error convert string to UTF-16: %v", err)
return fmt.Errorf("error convert string to UTF-16: %w", err)
}
ss := []*uint16{msg, nil, nil, nil, nil, nil, nil, nil, nil}
@ -104,7 +104,7 @@ func (l *eventlogLogger) putLoggerBuf(lb *loggerBuf) {
// PrioritySelector inspects the list of keyvals and selects an eventlog priority.
type PrioritySelector func(keyvals ...interface{}) Priority
// defaultPrioritySelector convert a kit/log level into a Windows Eventlog level
// defaultPrioritySelector convert a kit/log level into a Windows Eventlog level.
func defaultPrioritySelector(keyvals ...interface{}) Priority {
l := len(keyvals)

View File

@ -20,14 +20,14 @@ import (
promlogflag "github.com/prometheus/common/promlog/flag"
)
// FileFlagName is the canonical flag name to configure the log file
// FileFlagName is the canonical flag name to configure the log file.
const FileFlagName = "log.file"
// FileFlagHelp is the help description for the log.file flag.
const FileFlagHelp = "Output file of log messages. One of [stdout, stderr, eventlog, <path to log file>]"
// AddFlags adds the flags used by this package to the Kingpin application.
// To use the default Kingpin application, call AddFlags(kingpin.CommandLine)
// To use the default Kingpin application, call AddFlags(kingpin.CommandLine).
func AddFlags(a *kingpin.Application, config *log.Config) {
config.Level = &promlog.AllowedLevel{}
a.Flag(promlogflag.LevelFlagName, promlogflag.LevelFlagHelp).

View File

@ -33,7 +33,7 @@ func (f *AllowedFile) Set(s string) error {
case "eventlog":
f.w = nil
default:
file, err := os.OpenFile(s, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0200)
file, err := os.OpenFile(s, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o200)
if err != nil {
return err
}
@ -42,7 +42,7 @@ func (f *AllowedFile) Set(s string) error {
return nil
}
// Config is a struct containing configurable settings for the logger
// Config is a struct containing configurable settings for the logger.
type Config struct {
promlog.Config
@ -72,15 +72,17 @@ func New(config *Config) (log.Logger, error) {
return nil, fmt.Errorf("unsupported log.format %q", config.Format.String())
}
if config.File.s == "eventlog" {
switch {
case config.File.s == "eventlog":
w, err := goeventlog.Open("windows_exporter")
if err != nil {
return nil, err
}
l = eventlog.NewEventLogLogger(w, loggerFunc)
} else if config.File.w == nil {
case config.File.w == nil:
panic("logger: file writer is nil")
} else {
default:
l = loggerFunc(log.NewSyncWriter(config.File.w))
}

View File

@ -113,6 +113,7 @@ Data for some of the objects is also available through WMI:
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"io"
"strings"
@ -120,7 +121,7 @@ import (
"unsafe"
)
// TODO: There's a LittleEndian field in the PERF header - we ought to check it
// TODO: There's a LittleEndian field in the PERF header - we ought to check it.
var bo = binary.LittleEndian
const averageCount64Type = 1073874176
@ -204,9 +205,8 @@ func queryRawData(query string) ([]byte, error) {
buffer = make([]byte, bufLen)
name, err := syscall.UTF16PtrFromString(query)
if err != nil {
return nil, fmt.Errorf("failed to encode query string: %v", err)
return nil, fmt.Errorf("failed to encode query string: %w", err)
}
for {
@ -220,14 +220,15 @@ func queryRawData(query string) ([]byte, error) {
(*byte)(unsafe.Pointer(&buffer[0])),
&bufLen)
if err == error(syscall.ERROR_MORE_DATA) {
if errors.Is(err, error(syscall.ERROR_MORE_DATA)) {
newBuffer := make([]byte, len(buffer)+16384)
copy(newBuffer, buffer)
buffer = newBuffer
continue
} else if err != nil {
if errno, ok := err.(syscall.Errno); ok {
return nil, fmt.Errorf("ReqQueryValueEx failed: %v errno %d", err, uint(errno))
var errNo syscall.Errno
if errors.As(err, &errNo) {
return nil, fmt.Errorf("ReqQueryValueEx failed: %w errno %d", err, uint(errNo))
}
return nil, err
@ -266,7 +267,6 @@ more than you asked for.
*/
func QueryPerformanceData(query string) ([]*PerfObject, error) {
buffer, err := queryRawData(query)
if err != nil {
return nil, err
}
@ -277,7 +277,6 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
header := new(perfDataBlock)
err = header.BinaryReadFrom(r)
if err != nil {
return nil, fmt.Errorf("failed to read performance data block for %q with: %w", query, err)
}
@ -294,7 +293,7 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
objOffset := int64(header.HeaderLength)
for i := 0; i < numObjects; i++ {
for i := range numObjects {
_, err := r.Seek(objOffset, io.SeekStart)
if err != nil {
return nil, err
@ -328,7 +327,7 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
rawData: obj,
}
for i := 0; i < numCounterDefs; i++ {
for i := range numCounterDefs {
def := new(perfCounterDefinition)
err := def.BinaryReadFrom(r)
if err != nil {
@ -349,10 +348,10 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
}
}
if obj.NumInstances <= 0 {
if obj.NumInstances <= 0 { //nolint:nestif
blockOffset := objOffset + int64(obj.DefinitionLength)
_, err := r.Seek(blockOffset, io.SeekStart)
if err != nil {
if _, err := r.Seek(blockOffset, io.SeekStart); err != nil {
return nil, err
}
@ -370,20 +369,20 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
} else {
instOffset := objOffset + int64(obj.DefinitionLength)
for i := 0; i < numInstances; i++ {
_, err := r.Seek(instOffset, io.SeekStart)
if err != nil {
for i := range numInstances {
if _, err := r.Seek(instOffset, io.SeekStart); err != nil {
return nil, err
}
inst := new(perfInstanceDefinition)
err = inst.BinaryReadFrom(r)
if err != nil {
if err = inst.BinaryReadFrom(r); err != nil {
return nil, err
}
name, _ := readUTF16StringAtPos(r, instOffset+int64(inst.NameOffset), inst.NameLength)
pos := instOffset + int64(inst.ByteLength)
offset, counters, err := parseCounterBlock(buffer, r, pos, counterDefs)
if err != nil {
return nil, err
@ -438,6 +437,7 @@ func parseCounterBlock(b []byte, r io.ReadSeeker, pos int64, defs []*PerfCounter
return int64(block.ByteLength), counters, nil
}
//nolint:nonamedreturns
func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, valueOffset int64) (value int64) {
/*
We can safely ignore the type since we're not interested in anything except the raw value.

View File

@ -1,39 +1,9 @@
package perflib
import (
"fmt"
"testing"
)
func ExampleQueryPerformanceData() {
objects, err := QueryPerformanceData("2")
if err != nil {
panic(err)
}
for _, object := range objects {
fmt.Printf("%d %s [%d counters, %d instances]\n",
object.NameIndex, object.Name, len(object.CounterDefs), len(object.Instances))
for _, instance := range object.Instances {
if !((instance.Name == "_Total") || (instance.Name == "")) {
continue
}
if instance.Name == "" {
fmt.Println("No instance.", instance.Name)
} else {
fmt.Println("Instance:", instance.Name)
}
for _, counter := range instance.Counters {
fmt.Printf(" -> %s %d\n", counter.Def.Name, counter.Def.NameIndex)
}
}
}
}
func BenchmarkQueryPerformanceData(b *testing.B) {
for n := 0; n < b.N; n++ {
_, _ = QueryPerformanceData("Global")

View File

@ -10,7 +10,7 @@ import (
"github.com/go-kit/log/level"
)
// Conversion factors
// Conversion factors.
const (
TicksToSecondScaleFactor = 1 / 1e7
WindowsEpoch = 116444736000000000
@ -48,7 +48,7 @@ func UnmarshalObject(obj *PerfObject, vs interface{}, logger log.Logger) error {
}
}
for i := 0; i < target.NumField(); i++ {
for i := range target.NumField() {
f := rt.Field(i)
tag := f.Tag.Get("perflib")
if tag == "" {

View File

@ -6,17 +6,15 @@ import (
"syscall"
)
// readUTF16StringAtPos Read an unterminated UTF16 string at a given position, specifying its length
// readUTF16StringAtPos Read an unterminated UTF16 string at a given position, specifying its length.
func readUTF16StringAtPos(r io.ReadSeeker, absPos int64, length uint32) (string, error) {
value := make([]uint16, length/2)
_, err := r.Seek(absPos, io.SeekStart)
if err != nil {
return "", err
}
err = binary.Read(r, bo, value)
if err != nil {
return "", err
}
@ -24,7 +22,7 @@ func readUTF16StringAtPos(r io.ReadSeeker, absPos int64, length uint32) (string,
return syscall.UTF16ToString(value), nil
}
// readUTF16String Reads a null-terminated UTF16 string at the current offset
// readUTF16String Reads a null-terminated UTF16 string at the current offset.
func readUTF16String(r io.Reader) (string, error) {
var err error

View File

@ -14,6 +14,8 @@ type simple struct {
}
func TestUnmarshalPerflib(t *testing.T) {
t.Parallel()
cases := []struct {
name string
obj *PerfObject
@ -110,6 +112,8 @@ func TestUnmarshalPerflib(t *testing.T) {
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
t.Parallel()
output := make([]simple, 0)
err := UnmarshalObject(c.obj, &output, log.NewNopLogger())
if err != nil && !c.expectError {

View File

@ -13,6 +13,8 @@ import (
)
func FuncBenchmarkCollector[C collector.Collector](b *testing.B, name string, collectFunc collector.BuilderWithFlags[C]) {
b.Helper()
c := collectFunc(kingpin.CommandLine)
collectors := collector.New(map[string]collector.Collector{name: c})
require.NoError(b, collectors.Build())

View File

@ -14,13 +14,15 @@ import (
// Splits provided child Collectors and deduplicate.
func ExpandEnabledChildCollectors(enabled string) []string {
result := slices.Compact(strings.Split(enabled, ","))
// Ensure result is ordered, to prevent test failure
// Result must order, to prevent test failures.
sort.Strings(result)
return result
}
func ExpandEnabledCollectors(enabled string) []string {
expanded := strings.Replace(enabled, types.DefaultCollectorsPlaceholder, types.DefaultCollectors, -1)
expanded := strings.ReplaceAll(enabled, types.DefaultCollectorsPlaceholder, types.DefaultCollectors)
separated := strings.Split(expanded, ",")
unique := map[string]bool{}
for _, s := range separated {

View File

@ -11,6 +11,8 @@ import (
)
func TestExpandChildCollectors(t *testing.T) {
t.Parallel()
cases := []struct {
name string
input string
@ -30,6 +32,8 @@ func TestExpandChildCollectors(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
t.Parallel()
output := utils.ExpandEnabledChildCollectors(c.input)
if !reflect.DeepEqual(output, c.expectedOutput) {
t.Errorf("Output mismatch, expected %+v, got %+v", c.expectedOutput, output)
@ -39,6 +43,8 @@ func TestExpandChildCollectors(t *testing.T) {
}
func TestExpandEnabled(t *testing.T) {
t.Parallel()
expansionTests := []struct {
input string
expectedOutput []string

View File

@ -9,9 +9,12 @@ import (
"golang.org/x/sys/windows/registry"
)
var WindowsVersion string
var WindowsVersionFloat float64
var (
WindowsVersion string
WindowsVersionFloat float64
)
//nolint:gochecknoinits
func init() {
var err error
WindowsVersion, WindowsVersionFloat, err = GetWindowsVersion()

View File

@ -41,6 +41,9 @@ func QueryNamespace(query string, dst interface{}, namespace string) error {
return wmi.QueryNamespace(query, dst, namespace)
}
// QueryAll returns a query string that selects all fields from the given
// struct type.
// Deprecated: Use QueryAllForClass instead.
func QueryAll(src interface{}, logger log.Logger) string {
var b bytes.Buffer
b.WriteString("SELECT * FROM ")

View File

@ -29,6 +29,8 @@ var (
type queryFunc func(src interface{}, class string, where string) string
func TestCreateQuery(t *testing.T) {
t.Parallel()
cases := []struct {
desc string
dst interface{}
@ -109,6 +111,8 @@ func TestCreateQuery(t *testing.T) {
}
for _, c := range cases {
t.Run(c.desc, func(t *testing.T) {
t.Parallel()
if q := c.queryFunc(c.dst, c.class, c.where); q != c.expected {
t.Errorf("Case %q failed: Expected %q, got %q", c.desc, c.expected, q)
}

View File

@ -1,34 +0,0 @@
Param(
[Parameter(Mandatory=$true)]
$Class,
[Parameter(Mandatory=$false)]
$Namespace = "root/cimv2",
[Parameter(Mandatory=$false)]
$CollectorName = ($Class -replace 'Win32_PerfRawData_Perf',''),
[Parameter(Mandatory=$false)]
$ComputerName = "localhost",
[Parameter(Mandatory=$false)]
[CimSession] $Session
)
$ErrorActionPreference = "Stop"
if($null -ne $Session) {
$wmiObject = Get-CimInstance -CimSession $Session -Namespace $Namespace -Class $Class
}
else {
$wmiObject = Get-CimInstance -ComputerName $ComputerName -Namespace $Namespace -Class $Class
}
$members = $wmiObject `
| Get-Member -MemberType Properties `
| Where-Object { $_.Definition -Match '^u?int' -and $_.Name -NotMatch '_' } `
| Select-Object Name, @{Name="Type";Expression={$_.Definition.Split(" ")[0]}}
$input = @{
"Namespace"=$Namespace;
"Class"=$Class;
"CollectorName"=$CollectorName;
"Members"=$members
} | ConvertTo-Json
$outFileName = "..\..\collector\$CollectorName.go".ToLower()
$input | .\collector-generator.exe | Out-File -NoClobber -Encoding UTF8 $outFileName
go fmt $outFileName

View File

@ -1,17 +0,0 @@
# Collector generator
Generates a collector skeleton implementation from a WMI class.
## Usage
Build the generator:
```bash
go build .
```
Run the script to query the WMI service and send the output to the generator:
```powershell
.\New-Collector.ps1 -Class Win32_PerfRawData_PerfOS_Processor
```
This will generate a collector. The collector name is generated by first removing `Win32_PerfRawData_Perf` and lower-casing, so `Win32_PerfRawData_PerfOS_Processor` will generate `os_processor.go`. This can be overridden by passing `-CollectorName` to the script.

View File

@ -1,56 +0,0 @@
package collector
import (
"github.com/yusufpapurcu/wmi"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus-community/windows_exporter/log"
)
func init() {
registerCollector("{{ .CollectorName | toLower }}", new{{ .CollectorName }}Collector) // TODO: Add any perflib dependencies here
}
// A {{ .CollectorName }}Collector is a Prometheus collector for WMI {{ .Class }} metrics
type {{ .CollectorName }}Collector struct {
{{- range $m := .Members }}
{{ $m.Name }} *prometheus.Desc
{{- end }}
}
func new{{ .CollectorName }}Collector() (Collector, error) {
const subsystem = "{{ .CollectorName | toLower }}"
return &{{ .CollectorName }}Collector{
{{- range $m := .Members }}
{{ $m.Name }}: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "{{ $m.Name | toSnakeCase }}"),
"({{ $m.Name }})",
nil,
nil,
),
{{- end }}
}, nil
}
// {{ .Class }} docs:
// - <add link to documentation here>
type {{ .Class }} struct {
Name string
{{ range $m := .Members }}
{{ $m.Name }} {{ $m.Type }}
{{- end }}
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *{{ .CollectorName }}Collector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
var dst []{{ .Class }}
q := queryAll(&dst)
if err := wmi.Query(q, &dst); err != nil {
return nil, err
}
{{ range $m := .Members }}
ch <- prometheus.MustNewConstMetric(
c.{{ $m.Name }},
prometheus.GaugeValue,
float64(dst[0].{{ $m.Name }}),
)
{{ end }}
return nil, nil
}

View File

@ -1,60 +0,0 @@
package main
import (
"encoding/json"
"io/ioutil"
"os"
"strings"
"text/template"
"unicode"
)
type TemplateData struct {
CollectorName string
Class string
Members []Member
}
type Member struct {
Name string
Type string
}
func main() {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
panic(err)
}
var data TemplateData
if err = json.Unmarshal(bytes, &data); err != nil {
panic(err)
}
funcs := template.FuncMap{
"toLower": strings.ToLower,
"toSnakeCase": toSnakeCase,
}
tmpl, err := template.New("template").Funcs(funcs).ParseFiles("collector.template")
if err != nil {
panic(err)
}
err = tmpl.ExecuteTemplate(os.Stdout, "collector.template", data)
if err != nil {
panic(err)
}
}
// https://gist.github.com/elwinar/14e1e897fdbe4d3432e1
func toSnakeCase(in string) string {
runes := []rune(in)
length := len(runes)
var out []rune
for i := 0; i < length; i++ {
if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
out = append(out, '_')
}
out = append(out, unicode.ToLower(runes[i]))
}
return string(out)
}