mirror of
https://github.com/prometheus-community/windows_exporter
synced 2024-12-17 20:14:33 +00:00
chore: enable more linter (#1557)
This commit is contained in:
parent
27a3553dac
commit
9b02e4a0ea
@ -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:
|
||||
|
11
exporter.go
11
exporter.go
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
4
pkg/collector/cache/cache.go
vendored
4
pkg/collector/cache/cache.go
vendored
@ -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)
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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"`
|
||||
|
@ -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 {
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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[]"])
|
||||
|
@ -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
|
||||
|
@ -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"`
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
)
|
||||
|
||||
func TestIISDeduplication(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
start := []perflibAPP_POOL_WAS{
|
||||
{
|
||||
Name: "foo",
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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",
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"`
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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, "__", "_")
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"`
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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).
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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")
|
||||
|
@ -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 == "" {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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 ")
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
@ -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.
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user