mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-21 20:26:36 +00:00
chore: enable more linter (#1557)
This commit is contained in:
@@ -4,79 +4,49 @@ linters:
|
|||||||
- containedctx
|
- containedctx
|
||||||
- contextcheck
|
- contextcheck
|
||||||
- cyclop
|
- cyclop
|
||||||
- decorder
|
|
||||||
- depguard
|
- depguard
|
||||||
- dogsled
|
- dogsled
|
||||||
- dupl
|
- dupl
|
||||||
- dupword
|
|
||||||
- durationcheck
|
|
||||||
- err113
|
- err113
|
||||||
- errchkjson
|
|
||||||
- errname
|
|
||||||
- errorlint
|
|
||||||
- exhaustive
|
- exhaustive
|
||||||
- exhaustruct
|
- exhaustruct
|
||||||
- exportloopref
|
|
||||||
- fatcontext
|
- fatcontext
|
||||||
- funlen
|
- funlen
|
||||||
- ginkgolinter
|
|
||||||
- gocheckcompilerdirectives
|
|
||||||
- gochecknoglobals
|
- gochecknoglobals
|
||||||
- gochecknoinits
|
|
||||||
- gochecksumtype
|
|
||||||
- gocognit
|
- gocognit
|
||||||
- goconst
|
- goconst
|
||||||
- gocritic
|
|
||||||
- gocyclo
|
- gocyclo
|
||||||
- godot
|
|
||||||
- godox
|
- godox
|
||||||
- gofumpt
|
|
||||||
- goimports
|
|
||||||
- gomoddirectives
|
|
||||||
- gomodguard
|
|
||||||
- gosimple
|
|
||||||
- gosmopolitan
|
|
||||||
- grouper
|
|
||||||
- importas
|
|
||||||
- inamedparam
|
- inamedparam
|
||||||
- interfacebloat
|
|
||||||
- intrange
|
|
||||||
- ireturn
|
- ireturn
|
||||||
- lll
|
- lll
|
||||||
- maintidx
|
|
||||||
- mirror
|
|
||||||
- misspell
|
|
||||||
- mnd
|
- mnd
|
||||||
- musttag
|
|
||||||
- nakedret
|
|
||||||
- nestif
|
|
||||||
- nlreturn
|
- nlreturn
|
||||||
- noctx
|
- noctx
|
||||||
- nonamedreturns
|
|
||||||
- nosprintfhostport
|
|
||||||
- paralleltest
|
|
||||||
- predeclared
|
|
||||||
- protogetter
|
|
||||||
- reassign
|
|
||||||
- rowserrcheck
|
|
||||||
- sloglint
|
|
||||||
- spancheck
|
|
||||||
- sqlclosecheck
|
|
||||||
- staticcheck
|
|
||||||
- stylecheck
|
|
||||||
- tagalign
|
|
||||||
- tagliatelle
|
|
||||||
- tenv
|
|
||||||
- testableexamples
|
|
||||||
- testifylint
|
|
||||||
- testpackage
|
- testpackage
|
||||||
- thelper
|
|
||||||
- tparallel
|
|
||||||
- varnamelen
|
- varnamelen
|
||||||
- wrapcheck
|
- wrapcheck
|
||||||
- wsl
|
- wsl
|
||||||
- execinquery
|
- execinquery
|
||||||
- gomnd
|
- 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:
|
issues:
|
||||||
exclude:
|
exclude:
|
||||||
|
|||||||
11
exporter.go
11
exporter.go
@@ -4,7 +4,12 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
//goland:noinspection GoUnsortedImport
|
||||||
|
//nolint:gofumpt
|
||||||
import (
|
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"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -22,8 +27,6 @@ import (
|
|||||||
"github.com/go-kit/log/level"
|
"github.com/go-kit/log/level"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/config"
|
"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"
|
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/log/flag"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"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
|
const PROCESS_ALL_ACCESS = windows.STANDARD_RIGHTS_REQUIRED | windows.SYNCHRONIZE | windows.SPECIFIC_RIGHTS_ALL
|
||||||
|
|
||||||
// Same struct prometheus uses for their /version endpoint.
|
// 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 {
|
type prometheusVersion struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Revision string `json:"revision"`
|
Revision string `json:"revision"`
|
||||||
@@ -49,7 +52,7 @@ type prometheusVersion struct {
|
|||||||
GoVersion string `json:"goVersion"`
|
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{
|
var priorityStringToInt = map[string]uint32{
|
||||||
"realtime": windows.REALTIME_PRIORITY_CLASS,
|
"realtime": windows.REALTIME_PRIORITY_CLASS,
|
||||||
"high": windows.HIGH_PRIORITY_CLASS,
|
"high": windows.HIGH_PRIORITY_CLASS,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
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{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@ func (c *Collector) Build() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect implements the Collector interface
|
// Collect implements the Collector interface.
|
||||||
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting cache metrics", "err", err)
|
_ = 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"
|
"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 {
|
func NewWithFlags(app *kingpin.Application) Collectors {
|
||||||
collectors := map[string]Collector{}
|
collectors := map[string]Collector{}
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ func (c *Collectors) SetPerfCounterQuery() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable removes all collectors that not enabledCollectors
|
// Enable removes all collectors that not enabledCollectors.
|
||||||
func (c *Collectors) Enable(enabledCollectors []string) {
|
func (c *Collectors) Enable(enabledCollectors []string) {
|
||||||
for name := range c.collectors {
|
for name := range c.collectors {
|
||||||
if !slices.Contains(enabledCollectors, name) {
|
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 {
|
func (c *Collectors) Build() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ func (c *Collectors) Build() error {
|
|||||||
return nil
|
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) {
|
func (c *Collectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
|
||||||
objs, err := perflib.GetPerflibSnapshot(c.perfCounterQuery)
|
objs, err := perflib.GetPerflibSnapshot(c.perfCounterQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -227,7 +227,7 @@ func (c *Collectors) PrepareScrapeContext() (*types.ScrapeContext, error) {
|
|||||||
return &types.ScrapeContext{PerfObjects: objs}, nil
|
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 {
|
func (c *Collectors) Close() error {
|
||||||
errs := make([]error, 0, len(c.collectors))
|
errs := make([]error, 0, len(c.collectors))
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ type Config struct {
|
|||||||
Cs cs.Config `yaml:"cs"`
|
Cs cs.Config `yaml:"cs"`
|
||||||
DFSR dfsr.Config `yaml:"dfsr"`
|
DFSR dfsr.Config `yaml:"dfsr"`
|
||||||
Dhcp dhcp.Config `yaml:"dhcp"`
|
Dhcp dhcp.Config `yaml:"dhcp"`
|
||||||
DiskDrive diskdrive.Config `yaml:"diskdrive"`
|
DiskDrive diskdrive.Config `yaml:"diskdrive"` //nolint:tagliatelle
|
||||||
DNS dns.Config `yaml:"dns"`
|
DNS dns.Config `yaml:"dns"`
|
||||||
Exchange exchange.Config `yaml:"exchange"`
|
Exchange exchange.Config `yaml:"exchange"`
|
||||||
Fsrmquota fsrmquota.Config `yaml:"fsrmquota"`
|
Fsrmquota fsrmquota.Config `yaml:"fsrmquota"`
|
||||||
@@ -84,7 +84,7 @@ type Config struct {
|
|||||||
MsclusterNetwork mscluster_network.Config `yaml:"mscluster_network"`
|
MsclusterNetwork mscluster_network.Config `yaml:"mscluster_network"`
|
||||||
MsclusterNode mscluster_node.Config `yaml:"mscluster_node"`
|
MsclusterNode mscluster_node.Config `yaml:"mscluster_node"`
|
||||||
MsclusterResource mscluster_resource.Config `yaml:"mscluster_resource"`
|
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"`
|
Msmq msmq.Config `yaml:"msmq"`
|
||||||
Mssql mssql.Config `yaml:"mssql"`
|
Mssql mssql.Config `yaml:"mssql"`
|
||||||
Net net.Config `yaml:"net"`
|
Net net.Config `yaml:"net"`
|
||||||
@@ -105,7 +105,7 @@ type Config struct {
|
|||||||
ScheduledTask scheduled_task.Config `yaml:"scheduled_task"`
|
ScheduledTask scheduled_task.Config `yaml:"scheduled_task"`
|
||||||
Service service.Config `yaml:"service"`
|
Service service.Config `yaml:"service"`
|
||||||
SMB smb.Config `yaml:"smb"`
|
SMB smb.Config `yaml:"smb"`
|
||||||
SMBClient smbclient.Config `yaml:"smbclient"`
|
SMBClient smbclient.Config `yaml:"smbclient"` //nolint:tagliatelle
|
||||||
SMTP smtp.Config `yaml:"smtp"`
|
SMTP smtp.Config `yaml:"smtp"`
|
||||||
System system.Config `yaml:"system"`
|
System system.Config `yaml:"system"`
|
||||||
TeradiciPcoip teradici_pcoip.Config `yaml:"teradici_pcoip"`
|
TeradiciPcoip teradici_pcoip.Config `yaml:"teradici_pcoip"`
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for containers metrics
|
// A Collector is a Prometheus Collector for containers metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ type Collector struct {
|
|||||||
writeSizeBytes *prometheus.Desc
|
writeSizeBytes *prometheus.Desc
|
||||||
}
|
}
|
||||||
|
|
||||||
// New constructs a new Collector
|
// New constructs a new Collector.
|
||||||
func New(logger log.Logger, _ *Config) *Collector {
|
func New(logger log.Logger, _ *Config) *Collector {
|
||||||
c := &Collector{}
|
c := &Collector{}
|
||||||
c.SetLogger(logger)
|
c.SetLogger(logger)
|
||||||
@@ -205,7 +205,7 @@ func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// containerClose closes the container resource
|
// containerClose closes the container resource.
|
||||||
func (c *Collector) containerClose(container hcsshim.Container) {
|
func (c *Collector) containerClose(container hcsshim.Container) {
|
||||||
err := container.Close()
|
err := container.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ func (c *Collector) Close() error {
|
|||||||
func (c *Collector) Build() error {
|
func (c *Collector) Build() error {
|
||||||
c.cpuInfo = prometheus.NewDesc(
|
c.cpuInfo = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, "", Name),
|
prometheus.BuildFQName(types.Namespace, "", Name),
|
||||||
"Labelled CPU information as provided provided by Win32_Processor",
|
"Labelled CPU information as provided by Win32_Processor",
|
||||||
[]string{
|
[]string{
|
||||||
"architecture",
|
"architecture",
|
||||||
"device_id",
|
"device_id",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for WMI metrics
|
// A Collector is a Prometheus Collector for WMI metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ type Collector struct {
|
|||||||
type dfsrCollectorFunc func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error
|
type dfsrCollectorFunc func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error
|
||||||
|
|
||||||
// Map Perflib sources to DFSR Collector names
|
// 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 {
|
func dfsrGetPerfObjectName(collector string) string {
|
||||||
prefix := "DFS "
|
prefix := "DFS "
|
||||||
suffix := ""
|
suffix := ""
|
||||||
@@ -113,7 +113,7 @@ func New(logger log.Logger, config *Config) *Collector {
|
|||||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||||
return &Collector{
|
return &Collector{
|
||||||
dfsrEnabledCollectors: app.
|
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).
|
Default(ConfigDefaults.EnabledCollectors).
|
||||||
String(),
|
String(),
|
||||||
}
|
}
|
||||||
@@ -441,7 +441,7 @@ func (c *Collector) Build() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Maps enabled child collectors names to their relevant collection function,
|
// 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 {
|
func (c *Collector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCollectorFunc {
|
||||||
var dfsrCollectors []dfsrCollectorFunc
|
var dfsrCollectors []dfsrCollectorFunc
|
||||||
for _, collector := range enabledCollectors {
|
for _, collector := range enabledCollectors {
|
||||||
@@ -470,7 +470,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections"
|
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections".
|
||||||
type PerflibDFSRConnection struct {
|
type PerflibDFSRConnection struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -558,7 +558,7 @@ func (c *Collector) collectConnection(ctx *types.ScrapeContext, ch chan<- promet
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// perflibDFSRFolder Perflib: "DFS Replicated Folder"
|
// perflibDFSRFolder Perflib: "DFS Replicated Folder".
|
||||||
type perflibDFSRFolder struct {
|
type perflibDFSRFolder struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -790,7 +790,7 @@ func (c *Collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes"
|
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes".
|
||||||
type perflibDFSRVolume struct {
|
type perflibDFSRVolume struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector perflib DHCP metrics
|
// A Collector is a Prometheus Collector perflib DHCP metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -177,10 +177,10 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
|||||||
c.diskInfo,
|
c.diskInfo,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
1.0,
|
1.0,
|
||||||
strings.Trim(disk.DeviceID, "\\.\\"),
|
strings.Trim(disk.DeviceID, "\\.\\"), //nolint:staticcheck
|
||||||
strings.TrimRight(disk.Model, " "),
|
strings.TrimRight(disk.Model, " "),
|
||||||
strings.TrimRight(disk.Caption, " "),
|
strings.TrimRight(disk.Caption, " "),
|
||||||
strings.TrimRight(disk.Name, "\\.\\"),
|
strings.TrimRight(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, status := range allDiskStatus {
|
for _, status := range allDiskStatus {
|
||||||
@@ -193,7 +193,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
|||||||
c.status,
|
c.status,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
isCurrentState,
|
isCurrentState,
|
||||||
strings.Trim(disk.Name, "\\.\\"),
|
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||||
status,
|
status,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -202,14 +202,14 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
|||||||
c.size,
|
c.size,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(disk.Size),
|
float64(disk.Size),
|
||||||
strings.Trim(disk.Name, "\\.\\"),
|
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.partitions,
|
c.partitions,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(disk.Partitions),
|
float64(disk.Partitions),
|
||||||
strings.Trim(disk.Name, "\\.\\"),
|
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||||
)
|
)
|
||||||
|
|
||||||
for availNum, val := range availMap {
|
for availNum, val := range availMap {
|
||||||
@@ -221,7 +221,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
|||||||
c.availability,
|
c.availability,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
isCurrentState,
|
isCurrentState,
|
||||||
strings.Trim(disk.Name, "\\.\\"),
|
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||||
val,
|
val,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ type Collector struct {
|
|||||||
enabledCollectors []string
|
enabledCollectors []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// All available Collector functions
|
// All available Collector functions.
|
||||||
var exchangeAllCollectorNames = []string{
|
var exchangeAllCollectorNames = []string{
|
||||||
"ADAccessProcesses",
|
"ADAccessProcesses",
|
||||||
"TransportQueues",
|
"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.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.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.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.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.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")
|
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) {
|
if utils.IsEmpty(c.exchangeCollectorsEnabled) {
|
||||||
for _, collectorName := range exchangeAllCollectorNames {
|
c.enabledCollectors = append(c.enabledCollectors, exchangeAllCollectorNames...)
|
||||||
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for _, collectorName := range strings.Split(*c.exchangeCollectorsEnabled, ",") {
|
for _, collectorName := range strings.Split(*c.exchangeCollectorsEnabled, ",") {
|
||||||
if slices.Contains(exchangeAllCollectorNames, collectorName) {
|
if slices.Contains(exchangeAllCollectorNames, collectorName) {
|
||||||
@@ -236,7 +234,7 @@ func (c *Collector) Build() error {
|
|||||||
return nil
|
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 {
|
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
||||||
"ADAccessProcesses": c.collectADAccessProcesses,
|
"ADAccessProcesses": c.collectADAccessProcesses,
|
||||||
@@ -260,7 +258,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [19108] MSExchange ADAccess Processes
|
// Perflib: [19108] MSExchange ADAccess Processes.
|
||||||
type perflibADAccessProcesses struct {
|
type perflibADAccessProcesses struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -324,7 +322,7 @@ func (c *Collector) collectADAccessProcesses(ctx *types.ScrapeContext, ch chan<-
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [24914] MSExchange Availability Service
|
// Perflib: [24914] MSExchange Availability Service.
|
||||||
type perflibAvailabilityService struct {
|
type perflibAvailabilityService struct {
|
||||||
RequestsSec float64 `perflib:"Availability Requests (sec)"`
|
RequestsSec float64 `perflib:"Availability Requests (sec)"`
|
||||||
}
|
}
|
||||||
@@ -345,7 +343,7 @@ func (c *Collector) collectAvailabilityService(ctx *types.ScrapeContext, ch chan
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [36934] MSExchange HttpProxy
|
// Perflib: [36934] MSExchange HttpProxy.
|
||||||
type perflibHTTPProxy struct {
|
type perflibHTTPProxy struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -405,7 +403,7 @@ func (c *Collector) collectHTTPProxy(ctx *types.ScrapeContext, ch chan<- prometh
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [24618] MSExchange OWA
|
// Perflib: [24618] MSExchange OWA.
|
||||||
type perflibOWA struct {
|
type perflibOWA struct {
|
||||||
CurrentUniqueUsers float64 `perflib:"Current Unique Users"`
|
CurrentUniqueUsers float64 `perflib:"Current Unique Users"`
|
||||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||||
@@ -432,7 +430,7 @@ func (c *Collector) collectOWA(ctx *types.ScrapeContext, ch chan<- prometheus.Me
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [25138] MSExchange ActiveSync
|
// Perflib: [25138] MSExchange ActiveSync.
|
||||||
type perflibActiveSync struct {
|
type perflibActiveSync struct {
|
||||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||||
PingCommandsPending float64 `perflib:"Ping Commands Pending"`
|
PingCommandsPending float64 `perflib:"Ping Commands Pending"`
|
||||||
@@ -465,7 +463,7 @@ func (c *Collector) collectActiveSync(ctx *types.ScrapeContext, ch chan<- promet
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [29366] MSExchange RpcClientAccess
|
// Perflib: [29366] MSExchange RpcClientAccess.
|
||||||
type perflibRPCClientAccess struct {
|
type perflibRPCClientAccess struct {
|
||||||
RPCAveragedLatency float64 `perflib:"RPC Averaged Latency"`
|
RPCAveragedLatency float64 `perflib:"RPC Averaged Latency"`
|
||||||
RPCRequests float64 `perflib:"RPC Requests"`
|
RPCRequests float64 `perflib:"RPC Requests"`
|
||||||
@@ -517,7 +515,7 @@ func (c *Collector) collectRPC(ctx *types.ScrapeContext, ch chan<- prometheus.Me
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [20524] MSExchangeTransport Queues
|
// Perflib: [20524] MSExchangeTransport Queues.
|
||||||
type perflibTransportQueues struct {
|
type perflibTransportQueues struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -594,7 +592,7 @@ func (c *Collector) collectTransportQueues(ctx *types.ScrapeContext, ch chan<- p
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: [19430] MSExchange WorkloadManagement Workloads
|
// Perflib: [19430] MSExchange WorkloadManagement Workloads.
|
||||||
type perflibWorkloadManagementWorkloads struct {
|
type perflibWorkloadManagementWorkloads struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -651,7 +649,7 @@ func (c *Collector) collectWorkloadManagementWorkloads(ctx *types.ScrapeContext,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// [29240] MSExchangeAutodiscover
|
// [29240] MSExchangeAutodiscover.
|
||||||
type perflibAutodiscover struct {
|
type perflibAutodiscover struct {
|
||||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||||
}
|
}
|
||||||
@@ -671,7 +669,7 @@ func (c *Collector) collectAutoDiscover(ctx *types.ScrapeContext, ch chan<- prom
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// perflib [26463] MSExchange MapiHttp Emsmdb
|
// perflib [26463] MSExchange MapiHttp Emsmdb.
|
||||||
type perflibMapiHttpEmsmdb struct {
|
type perflibMapiHttpEmsmdb struct {
|
||||||
ActiveUserCount float64 `perflib:"Active User Count"`
|
ActiveUserCount float64 `perflib:"Active User Count"`
|
||||||
}
|
}
|
||||||
@@ -693,14 +691,14 @@ func (c *Collector) collectMapiHttpEmsmdb(ctx *types.ScrapeContext, ch chan<- pr
|
|||||||
return nil
|
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 {
|
func (c *Collector) toLabelName(name string) string {
|
||||||
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
|
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
|
||||||
s = strings.ReplaceAll(s, "__", "_")
|
s = strings.ReplaceAll(s, "__", "_")
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// msToSec converts from ms to seconds
|
// msToSec converts from ms to seconds.
|
||||||
func (c *Collector) msToSec(t float64) float64 {
|
func (c *Collector) msToSec(t float64) float64 {
|
||||||
return t / 1000
|
return t / 1000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func (c *Collectors) BuildServeHTTP(disableExporterMetrics bool, timeoutMargin f
|
|||||||
if timeoutSeconds == 0 {
|
if timeoutSeconds == 0 {
|
||||||
timeoutSeconds = defaultTimeout
|
timeoutSeconds = defaultTimeout
|
||||||
}
|
}
|
||||||
timeoutSeconds = timeoutSeconds - timeoutMargin
|
timeoutSeconds -= timeoutMargin
|
||||||
|
|
||||||
reg := prometheus.NewRegistry()
|
reg := prometheus.NewRegistry()
|
||||||
err, wc := collectorFactory(time.Duration(timeoutSeconds*float64(time.Second)), r.URL.Query()["collect[]"])
|
err, wc := collectorFactory(time.Duration(timeoutSeconds*float64(time.Second)), r.URL.Query()["collect[]"])
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// Collector is a Prometheus Collector for hyper-v
|
// Collector is a Prometheus Collector for hyper-v.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -810,7 +810,7 @@ func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary vm health status
|
// Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary vm health status.
|
||||||
type Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary struct {
|
type Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary struct {
|
||||||
HealthCritical uint32
|
HealthCritical uint32
|
||||||
HealthOk uint32
|
HealthOk uint32
|
||||||
@@ -840,7 +840,7 @@ func (c *Collector) collectVmHealth(ch chan<- prometheus.Metric) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition ..,
|
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition ..,.
|
||||||
type Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition struct {
|
type Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition struct {
|
||||||
Name string
|
Name string
|
||||||
PhysicalPagesAllocated uint64
|
PhysicalPagesAllocated uint64
|
||||||
|
|||||||
@@ -987,22 +987,22 @@ type perflibWebService struct {
|
|||||||
TotalUnlockRequests float64 `perflib:"Total Unlock Requests"`
|
TotalUnlockRequests float64 `perflib:"Total Unlock Requests"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fulfill the hasGetIISName interface
|
// Fulfill the hasGetIISName interface.
|
||||||
func (p perflibWebService) getIISName() string {
|
func (p perflibWebService) getIISName() string {
|
||||||
return p.Name
|
return p.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fulfill the hasGetIISName interface
|
// Fulfill the hasGetIISName interface.
|
||||||
func (p perflibAPP_POOL_WAS) getIISName() string {
|
func (p perflibAPP_POOL_WAS) getIISName() string {
|
||||||
return p.Name
|
return p.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fulfill the hasGetIISName interface
|
// Fulfill the hasGetIISName interface.
|
||||||
func (p perflibW3SVC_W3WP) getIISName() string {
|
func (p perflibW3SVC_W3WP) getIISName() string {
|
||||||
return p.Name
|
return p.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fulfill the hasGetIISName interface
|
// Fulfill the hasGetIISName interface.
|
||||||
func (p perflibW3SVC_W3WP_IIS8) getIISName() string {
|
func (p perflibW3SVC_W3WP_IIS8) getIISName() string {
|
||||||
return p.Name
|
return p.Name
|
||||||
}
|
}
|
||||||
@@ -1017,7 +1017,7 @@ type hasGetIISName interface {
|
|||||||
// E.G. Given the following list of site names, "Site_B" would be
|
// 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
|
// discarded, and "Site_B#2" would be kept and presented as "Site_B" in the
|
||||||
// Collector metrics.
|
// 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 {
|
func dedupIISNames[V hasGetIISName](services []V) map[string]V {
|
||||||
// Ensure IIS entry with the highest suffix occurs last
|
// Ensure IIS entry with the highest suffix occurs last
|
||||||
sort.SliceStable(services, func(i, j int) bool {
|
sort.SliceStable(services, func(i, j int) bool {
|
||||||
@@ -1457,13 +1457,13 @@ type perflibW3SVC_W3WP struct {
|
|||||||
|
|
||||||
URICacheFlushesTotal float64 `perflib:"Total Flushed URIs"`
|
URICacheFlushesTotal float64 `perflib:"Total Flushed URIs"`
|
||||||
URICacheFlushesTotalKernel 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"`
|
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"`
|
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"`
|
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"`
|
URIsCachedTotal float64 `perflib:"Total URIs Cached"`
|
||||||
URIsCachedTotalKernel float64 `perflib:"Total URIs Cached"`
|
URIsCachedTotalKernel float64 `perflib:"Total URIs Cached"`
|
||||||
URIsFlushedTotal float64 `perflib:"Total Flushed URIs"`
|
URIsFlushedTotal float64 `perflib:"Total Flushed URIs"`
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestIISDeduplication(t *testing.T) {
|
func TestIISDeduplication(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
start := []perflibAPP_POOL_WAS{
|
start := []perflibAPP_POOL_WAS{
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ var ConfigDefaults = Config{
|
|||||||
VolumeExclude: "",
|
VolumeExclude: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for perflib logicalDisk metrics
|
// A Collector is a Prometheus Collector for perflib logicalDisk metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
|
|
||||||
// Win32_PerfRawData_PerfDisk_LogicalDisk docs:
|
// 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/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 {
|
type logicalDisk struct {
|
||||||
Name string
|
Name string
|
||||||
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
|
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
|
||||||
@@ -478,7 +478,6 @@ func getDiskIDByVolume(rootDrive string) (string, error) {
|
|||||||
f, err = windows.CreateFile(
|
f, err = windows.CreateFile(
|
||||||
windows.StringToUTF16Ptr(`\\.\`+rootDrive),
|
windows.StringToUTF16Ptr(`\\.\`+rootDrive),
|
||||||
0, mode, nil, windows.OPEN_EXISTING, uint32(windows.FILE_ATTRIBUTE_READONLY), 0)
|
0, mode, nil, windows.OPEN_EXISTING, uint32(windows.FILE_ATTRIBUTE_READONLY), 0)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -527,7 +526,6 @@ func getVolumeInfo(rootDrive string) (volumeInfo, error) {
|
|||||||
|
|
||||||
err := windows.GetVolumeInformation(volPath, &volBufLabel[0], uint32(len(volBufLabel)),
|
err := windows.GetVolumeInformation(volPath, &volBufLabel[0], uint32(len(volBufLabel)),
|
||||||
&volSerialNum, nil, &fsFlags, &volBufType[0], uint32(len(volBufType)))
|
&volSerialNum, nil, &fsFlags, &volBufType[0], uint32(len(volBufType)))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if driveType != windows.DRIVE_CDROM && driveType != windows.DRIVE_REMOVABLE {
|
if driveType != windows.DRIVE_CDROM && driveType != windows.DRIVE_REMOVABLE {
|
||||||
return volumeInfo{}, err
|
return volumeInfo{}, err
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for WMI metrics
|
// A Collector is a Prometheus Collector for WMI metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// Variable used by mscluster_resource and mscluster_resourcegroup
|
// Variable used by mscluster_resource and mscluster_resourcegroup.
|
||||||
var NodeName []string
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ var ConfigDefaults = Config{
|
|||||||
QueryWhereClause: "",
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
const Name = "mssql"
|
const Name = "mssql"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
EnabledCollectors string `yaml:"collectors_enabled"`
|
EnabledCollectors string `yaml:"collectors_enabled"` //nolint:tagliatelle
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConfigDefaults = Config{
|
var ConfigDefaults = Config{
|
||||||
@@ -126,7 +126,7 @@ func mssqlGetPerfObjectName(sqlInstance string, collector string) string {
|
|||||||
return prefix + suffix
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ var ConfigDefaults = Config{
|
|||||||
|
|
||||||
var nicNameToUnderscore = regexp.MustCompile("[^a-zA-Z0-9]")
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNetworkToInstanceName(t *testing.T) {
|
func TestNetworkToInstanceName(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
data := map[string]string{
|
data := map[string]string{
|
||||||
"Intel[R] Dual Band Wireless-AC 8260": "Intel_R__Dual_Band_Wireless_AC_8260",
|
"Intel[R] Dual Band Wireless-AC 8260": "Intel_R__Dual_Band_Wireless_AC_8260",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_IAS_NPSAuthenticationServer docs:
|
// 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 {
|
type Win32_PerfRawData_IAS_NPSAuthenticationServer struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for WMI metrics
|
// A Collector is a Prometheus Collector for WMI metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Win32_OperatingSystem docs:
|
// 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 {
|
type Win32_OperatingSystem struct {
|
||||||
Caption string
|
Caption string
|
||||||
FreePhysicalMemory uint64
|
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.
|
// 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)
|
memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE)
|
||||||
defer memManKey.Close()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer memManKey.Close()
|
||||||
|
|
||||||
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
|
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
|
||||||
|
|
||||||
var fsipf float64
|
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
|
// Get build number and product name from registry
|
||||||
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||||
defer ntKey.Close()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer ntKey.Close()
|
||||||
|
|
||||||
pn, _, err := ntKey.GetStringValue("ProductName")
|
pn, _, err := ntKey.GetStringValue("ProductName")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ var ConfigDefaults = Config{
|
|||||||
DiskExclude: "",
|
DiskExclude: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for perflib PhysicalDisk metrics
|
// A Collector is a Prometheus Collector for perflib PhysicalDisk metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
|
|
||||||
// PhysicalDisk
|
// PhysicalDisk
|
||||||
// Win32_PerfRawData_PerfDisk_PhysicalDisk docs:
|
// 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 {
|
type PhysicalDisk struct {
|
||||||
Name string
|
Name string
|
||||||
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
|
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const Name = "process"
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
ProcessInclude string `yaml:"process_include"`
|
ProcessInclude string `yaml:"process_include"`
|
||||||
ProcessExclude string `yaml:"process_exclude"`
|
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"`
|
EnableReportOwner bool `yaml:"enable_report_owner"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +488,7 @@ func (c *Collector) getProcessOwner(pid int) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("OpenProcess: %T %w", err, err)
|
return "", fmt.Errorf("OpenProcess: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer windows.Close(p)
|
defer windows.Close(p)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ func (coll *Prometheus) Collect(ch chan<- prometheus.Metric) {
|
|||||||
time.Since(t).Seconds(),
|
time.Since(t).Seconds(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ func (c *Collector) collectRemoteFXGraphicsCounters(ctx *types.ScrapeContext, ch
|
|||||||
return nil
|
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 {
|
func normalizeSessionName(sessionName string) string {
|
||||||
return strings.Replace(sessionName, "RDP-tcp", "RDP-Tcp", 1)
|
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.
|
// S_FALSE is returned by CoInitialize if it was already called on this thread.
|
||||||
const S_FALSE = 0x00000001
|
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
|
// 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.
|
// ensure the CoInitialize[Ex]() call is bound to its current OS thread.
|
||||||
// Otherwise, attempting to initialize and run parallel queries across
|
// Otherwise, attempting to initialize and run parallel queries across
|
||||||
@@ -320,7 +322,9 @@ func fetchTasksRecursively(folder *ole.IDispatch, scheduledTasks *ScheduledTasks
|
|||||||
return err
|
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")
|
taskNameVar, err := oleutil.GetProperty(task, "Name")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return scheduledTask, err
|
return scheduledTask, err
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ var ConfigDefaults = Config{
|
|||||||
V2: false,
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ type Collector struct {
|
|||||||
enabledCollectors []string
|
enabledCollectors []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// All available Collector functions
|
// All available Collector functions.
|
||||||
var smbAllCollectorNames = []string{
|
var smbAllCollectorNames = []string{
|
||||||
"ServerShares",
|
"ServerShares",
|
||||||
}
|
}
|
||||||
@@ -121,9 +121,7 @@ func (c *Collector) Build() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *c.smbCollectorsEnabled == "" {
|
if *c.smbCollectorsEnabled == "" {
|
||||||
for _, collectorName := range smbAllCollectorNames {
|
c.enabledCollectors = append(c.enabledCollectors, smbAllCollectorNames...)
|
||||||
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for _, collectorName := range strings.Split(*c.smbCollectorsEnabled, ",") {
|
for _, collectorName := range strings.Split(*c.smbCollectorsEnabled, ",") {
|
||||||
if slices.Contains(smbAllCollectorNames, collectorName) {
|
if slices.Contains(smbAllCollectorNames, collectorName) {
|
||||||
@@ -137,7 +135,7 @@ func (c *Collector) Build() error {
|
|||||||
return nil
|
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 {
|
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
||||||
"ServerShares": c.collectServerShares,
|
"ServerShares": c.collectServerShares,
|
||||||
@@ -152,7 +150,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: SMB Server Shares
|
// Perflib: SMB Server Shares.
|
||||||
type perflibServerShares struct {
|
type perflibServerShares struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@@ -186,7 +184,7 @@ func (c *Collector) collectServerShares(ctx *types.ScrapeContext, ch chan<- prom
|
|||||||
return nil
|
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 {
|
func (c *Collector) toLabelName(name string) string {
|
||||||
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
|
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
|
||||||
s = strings.ReplaceAll(s, "__", "_")
|
s = strings.ReplaceAll(s, "__", "_")
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ type Collector struct {
|
|||||||
requestSecs *prometheus.Desc
|
requestSecs *prometheus.Desc
|
||||||
}
|
}
|
||||||
|
|
||||||
// All available collector functions
|
// All available collector functions.
|
||||||
var smbclientAllCollectorNames = []string{
|
var smbclientAllCollectorNames = []string{
|
||||||
"ClientShares",
|
"ClientShares",
|
||||||
}
|
}
|
||||||
@@ -224,9 +224,7 @@ func (c *Collector) Build() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *c.smbClientCollectorsEnabled == "" {
|
if *c.smbClientCollectorsEnabled == "" {
|
||||||
for _, collectorName := range smbclientAllCollectorNames {
|
c.enabledCollectors = append(c.enabledCollectors, smbclientAllCollectorNames...)
|
||||||
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for _, collectorName := range strings.Split(*c.smbClientCollectorsEnabled, ",") {
|
for _, collectorName := range strings.Split(*c.smbClientCollectorsEnabled, ",") {
|
||||||
if slices.Contains(smbclientAllCollectorNames, collectorName) {
|
if slices.Contains(smbclientAllCollectorNames, collectorName) {
|
||||||
@@ -240,7 +238,7 @@ func (c *Collector) Build() error {
|
|||||||
return nil
|
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 {
|
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
||||||
"ClientShares": c.collectClientShares,
|
"ClientShares": c.collectClientShares,
|
||||||
@@ -255,7 +253,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib: SMB Client Shares
|
// Perflib: SMB Client Shares.
|
||||||
type perflibClientShares struct {
|
type perflibClientShares struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PerflibSMTPServer Perflib: "SMTP Server"
|
// PerflibSMTPServer Perflib: "SMTP Server".
|
||||||
type PerflibSMTPServer struct {
|
type PerflibSMTPServer struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for WMI metrics
|
// A Collector is a Prometheus Collector for WMI metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ var ConfigDefaults = Config{}
|
|||||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics
|
// win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics
|
||||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics
|
// win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics
|
||||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
|
// win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
|
||||||
// win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics
|
// win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ func (c *Collector) GetPerfCounter() ([]string, error) {
|
|||||||
|
|
||||||
func (c *Collector) Close() error {
|
func (c *Collector) Close() error {
|
||||||
err := wtsapi32.WTSCloseServer(c.hServer)
|
err := wtsapi32.WTSCloseServer(c.hServer)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to close WTS server: %w", err)
|
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,
|
c.sessionInfo,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
isState,
|
isState,
|
||||||
strings.Replace(session.SessionName, "#", " ", -1),
|
strings.ReplaceAll(session.SessionName, "#", " "),
|
||||||
userName,
|
userName,
|
||||||
session.HostName,
|
session.HostName,
|
||||||
stateName,
|
stateName,
|
||||||
|
|||||||
@@ -120,21 +120,21 @@ func (c *Collector) Build() error {
|
|||||||
func duplicateMetricEntry(metricFamilies []*dto.MetricFamily) bool {
|
func duplicateMetricEntry(metricFamilies []*dto.MetricFamily) bool {
|
||||||
uniqueMetrics := make(map[string]map[string]string)
|
uniqueMetrics := make(map[string]map[string]string)
|
||||||
for _, metricFamily := range metricFamilies {
|
for _, metricFamily := range metricFamilies {
|
||||||
metric_name := *metricFamily.Name
|
metricName := metricFamily.GetName()
|
||||||
for _, metric := range metricFamily.Metric {
|
for _, metric := range metricFamily.GetMetric() {
|
||||||
metric_labels := metric.GetLabel()
|
metricLabels := metric.GetLabel()
|
||||||
labels := make(map[string]string)
|
labels := make(map[string]string)
|
||||||
for _, label := range metric_labels {
|
for _, label := range metricLabels {
|
||||||
labels[label.GetName()] = label.GetValue()
|
labels[label.GetName()] = label.GetValue()
|
||||||
}
|
}
|
||||||
// Check if key is present before appending
|
// Check if key is present before appending
|
||||||
_, mapContainsKey := uniqueMetrics[metric_name]
|
_, mapContainsKey := uniqueMetrics[metricName]
|
||||||
|
|
||||||
// Duplicate metric found with identical labels & label values
|
// 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
|
return true
|
||||||
}
|
}
|
||||||
uniqueMetrics[metric_name] = labels
|
uniqueMetrics[metricName] = labels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -145,7 +145,7 @@ func (c *Collector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<
|
|||||||
var val float64
|
var val float64
|
||||||
|
|
||||||
allLabelNames := map[string]struct{}{}
|
allLabelNames := map[string]struct{}{}
|
||||||
for _, metric := range metricFamily.Metric {
|
for _, metric := range metricFamily.GetMetric() {
|
||||||
labels := metric.GetLabel()
|
labels := metric.GetLabel()
|
||||||
for _, label := range labels {
|
for _, label := range labels {
|
||||||
if _, ok := allLabelNames[label.GetName()]; !ok {
|
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 {
|
if metric.TimestampMs != nil {
|
||||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Ignoring unsupported custom timestamp on textfile Collector metric %v", metric))
|
_ = 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
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if present == false {
|
if !present {
|
||||||
names = append(names, k)
|
names = append(names, k)
|
||||||
values = append(values, "")
|
values = append(values, "")
|
||||||
}
|
}
|
||||||
@@ -185,44 +185,44 @@ func (c *Collector) convertMetricFamily(metricFamily *dto.MetricFamily, ch chan<
|
|||||||
switch metricType {
|
switch metricType {
|
||||||
case dto.MetricType_COUNTER:
|
case dto.MetricType_COUNTER:
|
||||||
valType = prometheus.CounterValue
|
valType = prometheus.CounterValue
|
||||||
val = metric.Counter.GetValue()
|
val = metric.GetCounter().GetValue()
|
||||||
|
|
||||||
case dto.MetricType_GAUGE:
|
case dto.MetricType_GAUGE:
|
||||||
valType = prometheus.GaugeValue
|
valType = prometheus.GaugeValue
|
||||||
val = metric.Gauge.GetValue()
|
val = metric.GetGauge().GetValue()
|
||||||
|
|
||||||
case dto.MetricType_UNTYPED:
|
case dto.MetricType_UNTYPED:
|
||||||
valType = prometheus.UntypedValue
|
valType = prometheus.UntypedValue
|
||||||
val = metric.Untyped.GetValue()
|
val = metric.GetUntyped().GetValue()
|
||||||
|
|
||||||
case dto.MetricType_SUMMARY:
|
case dto.MetricType_SUMMARY:
|
||||||
quantiles := map[float64]float64{}
|
quantiles := map[float64]float64{}
|
||||||
for _, q := range metric.Summary.Quantile {
|
for _, q := range metric.GetSummary().GetQuantile() {
|
||||||
quantiles[q.GetQuantile()] = q.GetValue()
|
quantiles[q.GetQuantile()] = q.GetValue()
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstSummary(
|
ch <- prometheus.MustNewConstSummary(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
*metricFamily.Name,
|
metricFamily.GetName(),
|
||||||
metricFamily.GetHelp(),
|
metricFamily.GetHelp(),
|
||||||
names, nil,
|
names, nil,
|
||||||
),
|
),
|
||||||
metric.Summary.GetSampleCount(),
|
metric.GetSummary().GetSampleCount(),
|
||||||
metric.Summary.GetSampleSum(),
|
metric.GetSummary().GetSampleSum(),
|
||||||
quantiles, values...,
|
quantiles, values...,
|
||||||
)
|
)
|
||||||
case dto.MetricType_HISTOGRAM:
|
case dto.MetricType_HISTOGRAM:
|
||||||
buckets := map[float64]uint64{}
|
buckets := map[float64]uint64{}
|
||||||
for _, b := range metric.Histogram.Bucket {
|
for _, b := range metric.GetHistogram().GetBucket() {
|
||||||
buckets[b.GetUpperBound()] = b.GetCumulativeCount()
|
buckets[b.GetUpperBound()] = b.GetCumulativeCount()
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstHistogram(
|
ch <- prometheus.MustNewConstHistogram(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
*metricFamily.Name,
|
metricFamily.GetName(),
|
||||||
metricFamily.GetHelp(),
|
metricFamily.GetHelp(),
|
||||||
names, nil,
|
names, nil,
|
||||||
),
|
),
|
||||||
metric.Histogram.GetSampleCount(),
|
metric.GetHistogram().GetSampleCount(),
|
||||||
metric.Histogram.GetSampleSum(),
|
metric.GetHistogram().GetSampleSum(),
|
||||||
buckets, values...,
|
buckets, values...,
|
||||||
)
|
)
|
||||||
default:
|
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 {
|
if metricType == dto.MetricType_GAUGE || metricType == dto.MetricType_COUNTER || metricType == dto.MetricType_UNTYPED {
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
*metricFamily.Name,
|
metricFamily.GetName(),
|
||||||
metricFamily.GetHelp(),
|
metricFamily.GetHelp(),
|
||||||
names, nil,
|
names, nil,
|
||||||
),
|
),
|
||||||
@@ -266,7 +266,7 @@ type carriageReturnFilteringReader struct {
|
|||||||
r io.Reader
|
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) {
|
func (cr carriageReturnFilteringReader) Read(p []byte) (int, error) {
|
||||||
buf := make([]byte, len(p))
|
buf := make([]byte, len(p))
|
||||||
n, err := cr.r.Read(buf)
|
n, err := cr.r.Read(buf)
|
||||||
@@ -276,7 +276,7 @@ func (cr carriageReturnFilteringReader) Read(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pi := 0
|
pi := 0
|
||||||
for i := 0; i < n; i++ {
|
for i := range n {
|
||||||
if buf[i] != '\r' {
|
if buf[i] != '\r' {
|
||||||
p[pi] = buf[i]
|
p[pi] = buf[i]
|
||||||
pi++
|
pi++
|
||||||
@@ -380,7 +380,7 @@ func scrapeFile(path string, log log.Logger) ([]*dto.MetricFamily, error) {
|
|||||||
|
|
||||||
for _, mf := range parsedFamilies {
|
for _, mf := range parsedFamilies {
|
||||||
families_array = append(families_array, mf)
|
families_array = append(families_array, mf)
|
||||||
for _, m := range mf.Metric {
|
for _, m := range mf.GetMetric() {
|
||||||
if m.TimestampMs != nil {
|
if m.TimestampMs != nil {
|
||||||
return nil, errors.New("textfile contains unsupported client-side timestamps")
|
return nil, errors.New("textfile contains unsupported client-side timestamps")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCRFilter(t *testing.T) {
|
func TestCRFilter(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
sr := strings.NewReader("line 1\r\nline 2")
|
sr := strings.NewReader("line 1\r\nline 2")
|
||||||
cr := carriageReturnFilteringReader{r: sr}
|
cr := carriageReturnFilteringReader{r: sr}
|
||||||
b, err := io.ReadAll(cr)
|
b, err := io.ReadAll(cr)
|
||||||
@@ -23,6 +25,8 @@ func TestCRFilter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckBOM(t *testing.T) {
|
func TestCheckBOM(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
testdata := []struct {
|
testdata := []struct {
|
||||||
encoding utfbom.Encoding
|
encoding utfbom.Encoding
|
||||||
err string
|
err string
|
||||||
@@ -49,6 +53,8 @@ func TestCheckBOM(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDuplicateMetricEntry(t *testing.T) {
|
func TestDuplicateMetricEntry(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
metric_name := "windows_sometest"
|
metric_name := "windows_sometest"
|
||||||
metric_help := "This is a Test."
|
metric_help := "This is a Test."
|
||||||
metric_type := dto.MetricType_GAUGE
|
metric_type := dto.MetricType_GAUGE
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import (
|
|||||||
var baseDir = "../../../tools/textfile-test"
|
var baseDir = "../../../tools/textfile-test"
|
||||||
|
|
||||||
func TestMultipleDirectories(t *testing.T) {
|
func TestMultipleDirectories(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
testDir := baseDir + "/multiple-dirs"
|
testDir := baseDir + "/multiple-dirs"
|
||||||
testDirs := fmt.Sprintf("%[1]s/dir1,%[1]s/dir2,%[1]s/dir3", testDir)
|
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) {
|
func TestDuplicateFileName(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
testDir := baseDir + "/duplicate-filename"
|
testDir := baseDir + "/duplicate-filename"
|
||||||
textfileCollector := textfile.New(log.NewLogfmtLogger(os.Stdout), &textfile.Config{
|
textfileCollector := textfile.New(log.NewLogfmtLogger(os.Stdout), &textfile.Config{
|
||||||
TextFileDirectories: testDir,
|
TextFileDirectories: testDir,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
// Collector is a Prometheus Collector for Perflib counter metrics
|
// Collector is a Prometheus Collector for Perflib counter metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perflib "Windows Time Service"
|
// Perflib "Windows Time Service".
|
||||||
type windowsTime struct {
|
type windowsTime struct {
|
||||||
ClockFrequencyAdjustmentPPBTotal float64 `perflib:"Clock Frequency Adjustment (ppb)"`
|
ClockFrequencyAdjustmentPPBTotal float64 `perflib:"Clock Frequency Adjustment (ppb)"`
|
||||||
ComputedTimeOffset float64 `perflib:"Computed Time Offset"`
|
ComputedTimeOffset float64 `perflib:"Computed Time Offset"`
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ type Collectors struct {
|
|||||||
|
|
||||||
type Map map[string]Collector
|
type Map map[string]Collector
|
||||||
|
|
||||||
type Builder func(logger log.Logger) Collector
|
type (
|
||||||
type BuilderWithFlags[C Collector] func(*kingpin.Application) C
|
Builder func(logger log.Logger) Collector
|
||||||
|
BuilderWithFlags[C Collector] func(*kingpin.Application) C
|
||||||
|
)
|
||||||
|
|
||||||
// Collector interface that a collector has to implement.
|
// Collector interface that a collector has to implement.
|
||||||
type Collector interface {
|
type Collector interface {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
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 {
|
type Collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
|
||||||
|
|||||||
@@ -42,39 +42,24 @@ func NewResolver(file string, logger log.Logger, insecureSkipVerify bool) (*Reso
|
|||||||
var fileBytes []byte
|
var fileBytes []byte
|
||||||
var err error
|
var err error
|
||||||
if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") {
|
if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") {
|
||||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Loading configuration file from URL: %v", file))
|
fileBytes, err = readFromURL(file, logger, insecureSkipVerify)
|
||||||
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Loading configuration file: %v", file))
|
fileBytes, err = readFromFile(file, logger)
|
||||||
if _, err := os.Stat(file); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fileBytes, err = os.ReadFile(file)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawValues map[string]interface{}
|
var rawValues map[string]interface{}
|
||||||
|
|
||||||
err = yaml.Unmarshal(fileBytes, &rawValues)
|
err = yaml.Unmarshal(fileBytes, &rawValues)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flatten nested YAML values
|
// Flatten nested YAML values
|
||||||
flattenedValues := flatten(rawValues)
|
flattenedValues := flatten(rawValues)
|
||||||
for k, v := range flattenedValues {
|
for k, v := range flattenedValues {
|
||||||
@@ -82,9 +67,51 @@ func NewResolver(file string, logger log.Logger, insecureSkipVerify bool) (*Reso
|
|||||||
flags[k] = v
|
flags[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Resolver{flags: flags}, nil
|
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) {
|
func (c *Resolver) setDefault(v getFlagger) {
|
||||||
for name, value := range c.flags {
|
for name, value := range c.flags {
|
||||||
f := v.GetFlag(name)
|
f := v.GetFlag(name)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
//
|
//
|
||||||
// All keys will be joined by dot
|
// All keys will be joined by dot
|
||||||
// e.g. {"a": {"b":"c"}} => {"a.b":"c"}
|
// 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 {
|
func flatten(data map[string]interface{}) map[string]string {
|
||||||
ret := make(map[string]string)
|
ret := make(map[string]string)
|
||||||
for k, v := range data {
|
for k, v := range data {
|
||||||
@@ -32,6 +32,7 @@ func flatten(data map[string]interface{}) map[string]string {
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func flattenSlice(data []interface{}) map[string]string {
|
func flattenSlice(data []interface{}) map[string]string {
|
||||||
ret := make(map[string]string)
|
ret := make(map[string]string)
|
||||||
for idx, v := range data {
|
for idx, v := range data {
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"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) {
|
func TestConfigFlattening(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
goodYamlConfig := []byte(`---
|
goodYamlConfig := []byte(`---
|
||||||
|
|
||||||
collectors:
|
collectors:
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type wKSTAInfo102 struct {
|
|||||||
wki102_logged_on_users uint32
|
wki102_logged_on_users uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorkstationInfo is an idiomatic wrapper of WKSTAInfo102
|
// WorkstationInfo is an idiomatic wrapper of WKSTAInfo102.
|
||||||
type WorkstationInfo struct {
|
type WorkstationInfo struct {
|
||||||
PlatformId uint32
|
PlatformId uint32
|
||||||
ComputerName string
|
ComputerName string
|
||||||
@@ -89,7 +89,7 @@ func netWkstaGetInfo() (wKSTAInfo102, uint32, error) {
|
|||||||
return deref, 0, nil
|
return deref, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWorkstationInfo is an idiomatic wrapper for netWkstaGetInfo
|
// GetWorkstationInfo is an idiomatic wrapper for netWkstaGetInfo.
|
||||||
func GetWorkstationInfo() (WorkstationInfo, error) {
|
func GetWorkstationInfo() (WorkstationInfo, error) {
|
||||||
info, _, err := netWkstaGetInfo()
|
info, _, err := netWkstaGetInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const (
|
|||||||
SL_GEN_STATE_LAST
|
SL_GEN_STATE_LAST
|
||||||
)
|
)
|
||||||
|
|
||||||
// SLIsWindowsGenuineLocal function wrapper
|
// SLIsWindowsGenuineLocal function wrapper.
|
||||||
func SLIsWindowsGenuineLocal() (SL_GENUINE_STATE, error) {
|
func SLIsWindowsGenuineLocal() (SL_GENUINE_STATE, error) {
|
||||||
var genuineState SL_GENUINE_STATE
|
var genuineState SL_GENUINE_STATE
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ type memoryStatusEx struct {
|
|||||||
UllAvailExtendedVirtual uint64
|
UllAvailExtendedVirtual uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemoryStatus is an idiomatic wrapper for MemoryStatusEx
|
// MemoryStatus is an idiomatic wrapper for MemoryStatusEx.
|
||||||
type MemoryStatus struct {
|
type MemoryStatus struct {
|
||||||
MemoryLoad uint32
|
MemoryLoad uint32
|
||||||
TotalPhys uint64
|
TotalPhys uint64
|
||||||
@@ -40,17 +40,17 @@ type wProcessorArchitecture struct {
|
|||||||
WReserved uint16
|
WReserved uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessorArchitecture is an idiomatic wrapper for wProcessorArchitecture
|
// ProcessorArchitecture is an idiomatic wrapper for wProcessorArchitecture.
|
||||||
type ProcessorArchitecture uint16
|
type ProcessorArchitecture uint16
|
||||||
|
|
||||||
// Idiomatic values for wProcessorArchitecture
|
// Idiomatic values for wProcessorArchitecture.
|
||||||
const (
|
const (
|
||||||
AMD64 ProcessorArchitecture = 9
|
AMD64 ProcessorArchitecture = 9
|
||||||
ARM = 5
|
ARM ProcessorArchitecture = 5
|
||||||
ARM64 = 12
|
ARM64 ProcessorArchitecture = 12
|
||||||
IA64 = 6
|
IA64 ProcessorArchitecture = 6
|
||||||
INTEL = 0
|
INTEL ProcessorArchitecture = 0
|
||||||
UNKNOWN = 0xffff
|
UNKNOWN ProcessorArchitecture = 0xffff
|
||||||
)
|
)
|
||||||
|
|
||||||
// LpSystemInfo is a wrapper for LPSYSTEM_INFO
|
// LpSystemInfo is a wrapper for LPSYSTEM_INFO
|
||||||
@@ -68,7 +68,7 @@ type lpSystemInfo struct {
|
|||||||
WProcessorRevision uint16
|
WProcessorRevision uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemInfo is an idiomatic wrapper for LpSystemInfo
|
// SystemInfo is an idiomatic wrapper for LpSystemInfo.
|
||||||
type SystemInfo struct {
|
type SystemInfo struct {
|
||||||
Arch ProcessorArchitecture
|
Arch ProcessorArchitecture
|
||||||
PageSize uint32
|
PageSize uint32
|
||||||
@@ -82,10 +82,10 @@ type SystemInfo struct {
|
|||||||
ProcessorRevision uint16
|
ProcessorRevision uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// WinComputerNameFormat is a wrapper for COMPUTER_NAME_FORMAT
|
// WinComputerNameFormat is a wrapper for COMPUTER_NAME_FORMAT.
|
||||||
type WinComputerNameFormat int
|
type WinComputerNameFormat int
|
||||||
|
|
||||||
// Definitions for WinComputerNameFormat constants
|
// Definitions for WinComputerNameFormat constants.
|
||||||
const (
|
const (
|
||||||
ComputerNameNetBIOS WinComputerNameFormat = iota
|
ComputerNameNetBIOS WinComputerNameFormat = iota
|
||||||
ComputerNameDNSHostname
|
ComputerNameDNSHostname
|
||||||
@@ -112,7 +112,7 @@ func GlobalMemoryStatusEx() (MemoryStatus, error) {
|
|||||||
mse.dwLength = (uint32)(unsafe.Sizeof(mse))
|
mse.dwLength = (uint32)(unsafe.Sizeof(mse))
|
||||||
r1, _, err := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&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
|
return MemoryStatus{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
type WTSTypeClass int
|
type WTSTypeClass int
|
||||||
|
|
||||||
// The valid values for the WTSTypeClass enumeration
|
// The valid values for the WTSTypeClass enumeration.
|
||||||
const (
|
const (
|
||||||
WTSTypeProcessInfoLevel0 WTSTypeClass = iota
|
WTSTypeProcessInfoLevel0 WTSTypeClass = iota
|
||||||
WTSTypeProcessInfoLevel1
|
WTSTypeProcessInfoLevel1
|
||||||
@@ -138,11 +138,11 @@ func WTSCloseServer(server syscall.Handle) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func WTSFreeMemoryEx(class WTSTypeClass, pMemory uintptr, NumberOfEntries uint32) error {
|
func WTSFreeMemoryEx(class WTSTypeClass, pMemory uintptr, numberOfEntries uint32) error {
|
||||||
r1, _, err := procWTSFreeMemoryEx.Call(
|
r1, _, err := procWTSFreeMemoryEx.Call(
|
||||||
uintptr(class),
|
uintptr(class),
|
||||||
pMemory,
|
pMemory,
|
||||||
uintptr(NumberOfEntries),
|
uintptr(numberOfEntries),
|
||||||
)
|
)
|
||||||
|
|
||||||
if r1 != 1 {
|
if r1 != 1 {
|
||||||
@@ -182,7 +182,7 @@ func WTSEnumerateSessionsEx(server syscall.Handle, logger log.Logger) ([]WTSSess
|
|||||||
sessionSize := unsafe.Sizeof(sizeTest)
|
sessionSize := unsafe.Sizeof(sizeTest)
|
||||||
|
|
||||||
sessions := make([]WTSSession, 0, count)
|
sessions := make([]WTSSession, 0, count)
|
||||||
for i := uint32(0); i < count; i++ {
|
for i := range count {
|
||||||
curPtr := unsafe.Pointer(sessionInfoPointer + (uintptr(i) * sessionSize))
|
curPtr := unsafe.Pointer(sessionInfoPointer + (uintptr(i) * sessionSize))
|
||||||
data := (*wtsSessionInfo1)(curPtr)
|
data := (*wtsSessionInfo1)(curPtr)
|
||||||
|
|
||||||
|
|||||||
@@ -17,31 +17,32 @@ type windowsExporterService struct{}
|
|||||||
|
|
||||||
var logger *eventlog.Log
|
var logger *eventlog.Log
|
||||||
|
|
||||||
|
//nolint:nonamedreturns
|
||||||
func (s *windowsExporterService) Execute(_ []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
|
func (s *windowsExporterService) Execute(_ []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
|
||||||
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
|
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
|
||||||
changes <- svc.Status{State: svc.StartPending}
|
changes <- svc.Status{State: svc.StartPending}
|
||||||
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
||||||
loop:
|
|
||||||
for {
|
for c := range r {
|
||||||
select {
|
switch c.Cmd {
|
||||||
case c := <-r:
|
case svc.Interrogate:
|
||||||
switch c.Cmd {
|
changes <- c.CurrentStatus
|
||||||
case svc.Interrogate:
|
case svc.Stop, svc.Shutdown:
|
||||||
changes <- c.CurrentStatus
|
_ = logger.Info(100, "Service Stop Received")
|
||||||
case svc.Stop, svc.Shutdown:
|
changes <- svc.Status{State: svc.StopPending}
|
||||||
_ = logger.Info(100, "Service Stop Received")
|
|
||||||
changes <- svc.Status{State: svc.StopPending}
|
return
|
||||||
break loop
|
default:
|
||||||
default:
|
_ = logger.Error(102, fmt.Sprintf("unexpected control request #%d", c))
|
||||||
_ = logger.Error(102, fmt.Sprintf("unexpected control request #%d", c))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var StopCh = make(chan bool)
|
var StopCh = make(chan bool)
|
||||||
|
|
||||||
|
//nolint:gochecknoinits
|
||||||
func init() {
|
func init() {
|
||||||
isService, err := svc.IsWindowsService()
|
isService, err := svc.IsWindowsService()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func (l *eventlogLogger) Log(keyvals ...interface{}) error {
|
|||||||
|
|
||||||
msg, err := syscall.UTF16PtrFromString(lb.buf.String())
|
msg, err := syscall.UTF16PtrFromString(lb.buf.String())
|
||||||
if err != nil {
|
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}
|
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.
|
// PrioritySelector inspects the list of keyvals and selects an eventlog priority.
|
||||||
type PrioritySelector func(keyvals ...interface{}) 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 {
|
func defaultPrioritySelector(keyvals ...interface{}) Priority {
|
||||||
l := len(keyvals)
|
l := len(keyvals)
|
||||||
|
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ import (
|
|||||||
promlogflag "github.com/prometheus/common/promlog/flag"
|
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"
|
const FileFlagName = "log.file"
|
||||||
|
|
||||||
// FileFlagHelp is the help description for the log.file flag.
|
// 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>]"
|
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.
|
// 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) {
|
func AddFlags(a *kingpin.Application, config *log.Config) {
|
||||||
config.Level = &promlog.AllowedLevel{}
|
config.Level = &promlog.AllowedLevel{}
|
||||||
a.Flag(promlogflag.LevelFlagName, promlogflag.LevelFlagHelp).
|
a.Flag(promlogflag.LevelFlagName, promlogflag.LevelFlagHelp).
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (f *AllowedFile) Set(s string) error {
|
|||||||
case "eventlog":
|
case "eventlog":
|
||||||
f.w = nil
|
f.w = nil
|
||||||
default:
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ func (f *AllowedFile) Set(s string) error {
|
|||||||
return nil
|
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 {
|
type Config struct {
|
||||||
promlog.Config
|
promlog.Config
|
||||||
|
|
||||||
@@ -72,15 +72,17 @@ func New(config *Config) (log.Logger, error) {
|
|||||||
return nil, fmt.Errorf("unsupported log.format %q", config.Format.String())
|
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")
|
w, err := goeventlog.Open("windows_exporter")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
l = eventlog.NewEventLogLogger(w, loggerFunc)
|
l = eventlog.NewEventLogLogger(w, loggerFunc)
|
||||||
} else if config.File.w == nil {
|
case config.File.w == nil:
|
||||||
panic("logger: file writer is nil")
|
panic("logger: file writer is nil")
|
||||||
} else {
|
default:
|
||||||
l = loggerFunc(log.NewSyncWriter(config.File.w))
|
l = loggerFunc(log.NewSyncWriter(config.File.w))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ Data for some of the objects is also available through WMI:
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -120,7 +121,7 @@ import (
|
|||||||
"unsafe"
|
"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
|
var bo = binary.LittleEndian
|
||||||
|
|
||||||
const averageCount64Type = 1073874176
|
const averageCount64Type = 1073874176
|
||||||
@@ -204,9 +205,8 @@ func queryRawData(query string) ([]byte, error) {
|
|||||||
buffer = make([]byte, bufLen)
|
buffer = make([]byte, bufLen)
|
||||||
|
|
||||||
name, err := syscall.UTF16PtrFromString(query)
|
name, err := syscall.UTF16PtrFromString(query)
|
||||||
|
|
||||||
if err != nil {
|
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 {
|
for {
|
||||||
@@ -220,14 +220,15 @@ func queryRawData(query string) ([]byte, error) {
|
|||||||
(*byte)(unsafe.Pointer(&buffer[0])),
|
(*byte)(unsafe.Pointer(&buffer[0])),
|
||||||
&bufLen)
|
&bufLen)
|
||||||
|
|
||||||
if err == error(syscall.ERROR_MORE_DATA) {
|
if errors.Is(err, error(syscall.ERROR_MORE_DATA)) {
|
||||||
newBuffer := make([]byte, len(buffer)+16384)
|
newBuffer := make([]byte, len(buffer)+16384)
|
||||||
copy(newBuffer, buffer)
|
copy(newBuffer, buffer)
|
||||||
buffer = newBuffer
|
buffer = newBuffer
|
||||||
continue
|
continue
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
if errno, ok := err.(syscall.Errno); ok {
|
var errNo syscall.Errno
|
||||||
return nil, fmt.Errorf("ReqQueryValueEx failed: %v errno %d", err, uint(errno))
|
if errors.As(err, &errNo) {
|
||||||
|
return nil, fmt.Errorf("ReqQueryValueEx failed: %w errno %d", err, uint(errNo))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -266,7 +267,6 @@ more than you asked for.
|
|||||||
*/
|
*/
|
||||||
func QueryPerformanceData(query string) ([]*PerfObject, error) {
|
func QueryPerformanceData(query string) ([]*PerfObject, error) {
|
||||||
buffer, err := queryRawData(query)
|
buffer, err := queryRawData(query)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -277,7 +277,6 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
|
|||||||
|
|
||||||
header := new(perfDataBlock)
|
header := new(perfDataBlock)
|
||||||
err = header.BinaryReadFrom(r)
|
err = header.BinaryReadFrom(r)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read performance data block for %q with: %w", query, err)
|
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)
|
objOffset := int64(header.HeaderLength)
|
||||||
|
|
||||||
for i := 0; i < numObjects; i++ {
|
for i := range numObjects {
|
||||||
_, err := r.Seek(objOffset, io.SeekStart)
|
_, err := r.Seek(objOffset, io.SeekStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -328,7 +327,7 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
|
|||||||
rawData: obj,
|
rawData: obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < numCounterDefs; i++ {
|
for i := range numCounterDefs {
|
||||||
def := new(perfCounterDefinition)
|
def := new(perfCounterDefinition)
|
||||||
err := def.BinaryReadFrom(r)
|
err := def.BinaryReadFrom(r)
|
||||||
if err != nil {
|
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)
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,20 +369,20 @@ func QueryPerformanceData(query string) ([]*PerfObject, error) {
|
|||||||
} else {
|
} else {
|
||||||
instOffset := objOffset + int64(obj.DefinitionLength)
|
instOffset := objOffset + int64(obj.DefinitionLength)
|
||||||
|
|
||||||
for i := 0; i < numInstances; i++ {
|
for i := range numInstances {
|
||||||
_, err := r.Seek(instOffset, io.SeekStart)
|
if _, err := r.Seek(instOffset, io.SeekStart); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
inst := new(perfInstanceDefinition)
|
inst := new(perfInstanceDefinition)
|
||||||
err = inst.BinaryReadFrom(r)
|
|
||||||
if err != nil {
|
if err = inst.BinaryReadFrom(r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
name, _ := readUTF16StringAtPos(r, instOffset+int64(inst.NameOffset), inst.NameLength)
|
name, _ := readUTF16StringAtPos(r, instOffset+int64(inst.NameOffset), inst.NameLength)
|
||||||
pos := instOffset + int64(inst.ByteLength)
|
pos := instOffset + int64(inst.ByteLength)
|
||||||
|
|
||||||
offset, counters, err := parseCounterBlock(buffer, r, pos, counterDefs)
|
offset, counters, err := parseCounterBlock(buffer, r, pos, counterDefs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -438,6 +437,7 @@ func parseCounterBlock(b []byte, r io.ReadSeeker, pos int64, defs []*PerfCounter
|
|||||||
return int64(block.ByteLength), counters, nil
|
return int64(block.ByteLength), counters, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:nonamedreturns
|
||||||
func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, valueOffset int64) (value int64) {
|
func convertCounterValue(counterDef *perfCounterDefinition, buffer []byte, valueOffset int64) (value int64) {
|
||||||
/*
|
/*
|
||||||
We can safely ignore the type since we're not interested in anything except the raw value.
|
We can safely ignore the type since we're not interested in anything except the raw value.
|
||||||
|
|||||||
@@ -1,39 +1,9 @@
|
|||||||
package perflib
|
package perflib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"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) {
|
func BenchmarkQueryPerformanceData(b *testing.B) {
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
_, _ = QueryPerformanceData("Global")
|
_, _ = QueryPerformanceData("Global")
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/go-kit/log/level"
|
"github.com/go-kit/log/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Conversion factors
|
// Conversion factors.
|
||||||
const (
|
const (
|
||||||
TicksToSecondScaleFactor = 1 / 1e7
|
TicksToSecondScaleFactor = 1 / 1e7
|
||||||
WindowsEpoch = 116444736000000000
|
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)
|
f := rt.Field(i)
|
||||||
tag := f.Tag.Get("perflib")
|
tag := f.Tag.Get("perflib")
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
|
|||||||
@@ -6,17 +6,15 @@ import (
|
|||||||
"syscall"
|
"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) {
|
func readUTF16StringAtPos(r io.ReadSeeker, absPos int64, length uint32) (string, error) {
|
||||||
value := make([]uint16, length/2)
|
value := make([]uint16, length/2)
|
||||||
_, err := r.Seek(absPos, io.SeekStart)
|
_, err := r.Seek(absPos, io.SeekStart)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = binary.Read(r, bo, value)
|
err = binary.Read(r, bo, value)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -24,7 +22,7 @@ func readUTF16StringAtPos(r io.ReadSeeker, absPos int64, length uint32) (string,
|
|||||||
return syscall.UTF16ToString(value), nil
|
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) {
|
func readUTF16String(r io.Reader) (string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ type simple struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUnmarshalPerflib(t *testing.T) {
|
func TestUnmarshalPerflib(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
obj *PerfObject
|
obj *PerfObject
|
||||||
@@ -110,6 +112,8 @@ func TestUnmarshalPerflib(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
t.Run(c.name, func(t *testing.T) {
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
output := make([]simple, 0)
|
output := make([]simple, 0)
|
||||||
err := UnmarshalObject(c.obj, &output, log.NewNopLogger())
|
err := UnmarshalObject(c.obj, &output, log.NewNopLogger())
|
||||||
if err != nil && !c.expectError {
|
if err != nil && !c.expectError {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func FuncBenchmarkCollector[C collector.Collector](b *testing.B, name string, collectFunc collector.BuilderWithFlags[C]) {
|
func FuncBenchmarkCollector[C collector.Collector](b *testing.B, name string, collectFunc collector.BuilderWithFlags[C]) {
|
||||||
|
b.Helper()
|
||||||
|
|
||||||
c := collectFunc(kingpin.CommandLine)
|
c := collectFunc(kingpin.CommandLine)
|
||||||
collectors := collector.New(map[string]collector.Collector{name: c})
|
collectors := collector.New(map[string]collector.Collector{name: c})
|
||||||
require.NoError(b, collectors.Build())
|
require.NoError(b, collectors.Build())
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ import (
|
|||||||
// Splits provided child Collectors and deduplicate.
|
// Splits provided child Collectors and deduplicate.
|
||||||
func ExpandEnabledChildCollectors(enabled string) []string {
|
func ExpandEnabledChildCollectors(enabled string) []string {
|
||||||
result := slices.Compact(strings.Split(enabled, ","))
|
result := slices.Compact(strings.Split(enabled, ","))
|
||||||
// Ensure result is ordered, to prevent test failure
|
|
||||||
|
// Result must order, to prevent test failures.
|
||||||
sort.Strings(result)
|
sort.Strings(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExpandEnabledCollectors(enabled string) []string {
|
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, ",")
|
separated := strings.Split(expanded, ",")
|
||||||
unique := map[string]bool{}
|
unique := map[string]bool{}
|
||||||
for _, s := range separated {
|
for _, s := range separated {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestExpandChildCollectors(t *testing.T) {
|
func TestExpandChildCollectors(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
input string
|
input string
|
||||||
@@ -30,6 +32,8 @@ func TestExpandChildCollectors(t *testing.T) {
|
|||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
t.Run(c.name, func(t *testing.T) {
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
output := utils.ExpandEnabledChildCollectors(c.input)
|
output := utils.ExpandEnabledChildCollectors(c.input)
|
||||||
if !reflect.DeepEqual(output, c.expectedOutput) {
|
if !reflect.DeepEqual(output, c.expectedOutput) {
|
||||||
t.Errorf("Output mismatch, expected %+v, got %+v", c.expectedOutput, output)
|
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) {
|
func TestExpandEnabled(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
expansionTests := []struct {
|
expansionTests := []struct {
|
||||||
input string
|
input string
|
||||||
expectedOutput []string
|
expectedOutput []string
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ import (
|
|||||||
"golang.org/x/sys/windows/registry"
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
var WindowsVersion string
|
var (
|
||||||
var WindowsVersionFloat float64
|
WindowsVersion string
|
||||||
|
WindowsVersionFloat float64
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:gochecknoinits
|
||||||
func init() {
|
func init() {
|
||||||
var err error
|
var err error
|
||||||
WindowsVersion, WindowsVersionFloat, err = GetWindowsVersion()
|
WindowsVersion, WindowsVersionFloat, err = GetWindowsVersion()
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ func QueryNamespace(query string, dst interface{}, namespace string) error {
|
|||||||
return wmi.QueryNamespace(query, dst, namespace)
|
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 {
|
func QueryAll(src interface{}, logger log.Logger) string {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
b.WriteString("SELECT * FROM ")
|
b.WriteString("SELECT * FROM ")
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ var (
|
|||||||
type queryFunc func(src interface{}, class string, where string) string
|
type queryFunc func(src interface{}, class string, where string) string
|
||||||
|
|
||||||
func TestCreateQuery(t *testing.T) {
|
func TestCreateQuery(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
desc string
|
desc string
|
||||||
dst interface{}
|
dst interface{}
|
||||||
@@ -109,6 +111,8 @@ func TestCreateQuery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
t.Run(c.desc, func(t *testing.T) {
|
t.Run(c.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
if q := c.queryFunc(c.dst, c.class, c.where); q != c.expected {
|
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)
|
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)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user