mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-03-02 16:46:35 +00:00
feat: Add config file validation (#2011)
This commit is contained in:
@@ -19,6 +19,7 @@ linters:
|
|||||||
- maintidx
|
- maintidx
|
||||||
- mnd
|
- mnd
|
||||||
- paralleltest
|
- paralleltest
|
||||||
|
- tagliatelle
|
||||||
- testpackage
|
- testpackage
|
||||||
- varnamelen
|
- varnamelen
|
||||||
- wrapcheck
|
- wrapcheck
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import (
|
|||||||
const Name = "dfsr"
|
const Name = "dfsr"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"sources-enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import (
|
|||||||
const Name = "filetime"
|
const Name = "filetime"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
FilePatterns []string
|
FilePatterns []string `yaml:"file-patterns"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ import (
|
|||||||
const Name = "iis"
|
const Name = "iis"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
SiteInclude *regexp.Regexp `yaml:"site_include"`
|
SiteInclude *regexp.Regexp `yaml:"site-include"`
|
||||||
SiteExclude *regexp.Regexp `yaml:"site_exclude"`
|
SiteExclude *regexp.Regexp `yaml:"site-exclude"`
|
||||||
AppInclude *regexp.Regexp `yaml:"app_include"`
|
AppInclude *regexp.Regexp `yaml:"app-include"`
|
||||||
AppExclude *regexp.Regexp `yaml:"app_exclude"`
|
AppExclude *regexp.Regexp `yaml:"app-exclude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ import (
|
|||||||
const Name = "logical_disk"
|
const Name = "logical_disk"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
VolumeInclude *regexp.Regexp `yaml:"volume_include"`
|
VolumeInclude *regexp.Regexp `yaml:"volume-include"`
|
||||||
VolumeExclude *regexp.Regexp `yaml:"volume_exclude"`
|
VolumeExclude *regexp.Regexp `yaml:"volume-exclude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
NicExclude *regexp.Regexp `yaml:"nic_exclude"`
|
NicExclude *regexp.Regexp `yaml:"nic-exclude"`
|
||||||
NicInclude *regexp.Regexp `yaml:"nic_include"`
|
NicInclude *regexp.Regexp `yaml:"nic-include"`
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import (
|
|||||||
const Name = "netframework"
|
const Name = "netframework"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package performancecounter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Object struct {
|
type Object struct {
|
||||||
@@ -41,3 +42,7 @@ type Counter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/54691ebe11bb9ec32b4e35cd31fcb94a352de134/receiver/windowsperfcountersreceiver/README.md?plain=1#L150
|
// https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/54691ebe11bb9ec32b4e35cd31fcb94a352de134/receiver/windowsperfcountersreceiver/README.md?plain=1#L150
|
||||||
|
|
||||||
|
func (*Config) UnmarshalYAML(*yaml.Node) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ import (
|
|||||||
const Name = "physical_disk"
|
const Name = "physical_disk"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DiskInclude *regexp.Regexp `yaml:"disk_include"`
|
DiskInclude *regexp.Regexp `yaml:"disk-include"`
|
||||||
DiskExclude *regexp.Regexp `yaml:"disk_exclude"`
|
DiskExclude *regexp.Regexp `yaml:"disk-exclude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ var printerStatusMap = map[uint16]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
PrinterInclude *regexp.Regexp `yaml:"printer_include"`
|
PrinterInclude *regexp.Regexp `yaml:"include"`
|
||||||
PrinterExclude *regexp.Regexp `yaml:"printer_exclude"`
|
PrinterExclude *regexp.Regexp `yaml:"exclude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ import (
|
|||||||
const Name = "process"
|
const Name = "process"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ProcessInclude *regexp.Regexp `yaml:"process_include"`
|
ProcessInclude *regexp.Regexp `yaml:"include"`
|
||||||
ProcessExclude *regexp.Regexp `yaml:"process_exclude"`
|
ProcessExclude *regexp.Regexp `yaml:"exclude"`
|
||||||
EnableWorkerProcess bool `yaml:"enable_iis_worker_process"` //nolint:tagliatelle
|
EnableWorkerProcess bool `yaml:"iis"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ import (
|
|||||||
const Name = "scheduled_task"
|
const Name = "scheduled_task"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
TaskExclude *regexp.Regexp `yaml:"task_exclude"`
|
TaskExclude *regexp.Regexp `yaml:"exclude"`
|
||||||
TaskInclude *regexp.Regexp `yaml:"task_include"`
|
TaskInclude *regexp.Regexp `yaml:"include"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ import (
|
|||||||
const Name = "service"
|
const Name = "service"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ServiceInclude *regexp.Regexp `yaml:"service_include"`
|
ServiceInclude *regexp.Regexp `yaml:"include"`
|
||||||
ServiceExclude *regexp.Regexp `yaml:"service_exclude"`
|
ServiceExclude *regexp.Regexp `yaml:"exclude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ import (
|
|||||||
const Name = "smtp"
|
const Name = "smtp"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ServerInclude *regexp.Regexp `yaml:"server_include"`
|
ServerInclude *regexp.Regexp `yaml:"server-include"`
|
||||||
ServerExclude *regexp.Regexp `yaml:"server_exclude"`
|
ServerExclude *regexp.Regexp `yaml:"server-exclude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import (
|
|||||||
const Name = "tcp"
|
const Name = "tcp"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import (
|
|||||||
const Name = "textfile"
|
const Name = "textfile"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
TextFileDirectories []string `yaml:"text_file_directories"`
|
TextFileDirectories []string `yaml:"directories"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
CollectorsEnabled []string `yaml:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
|
|||||||
@@ -19,13 +19,49 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// configFile represents the structure of the windows_exporter configuration file,
|
||||||
|
// including configuration from the collector and web packages.
|
||||||
|
type configFile struct {
|
||||||
|
Debug struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
} `yaml:"debug"`
|
||||||
|
Collectors struct {
|
||||||
|
Enabled string `yaml:"enabled"`
|
||||||
|
} `yaml:"collectors"`
|
||||||
|
Collector collector.Config `yaml:"collector"`
|
||||||
|
Log struct {
|
||||||
|
Level string `yaml:"level"`
|
||||||
|
Format string `yaml:"format"`
|
||||||
|
File string `yaml:"file"`
|
||||||
|
} `yaml:"log"`
|
||||||
|
Process struct {
|
||||||
|
Priority string `yaml:"priority"`
|
||||||
|
MemoryLimit string `yaml:"memory-limit"`
|
||||||
|
} `yaml:"process"`
|
||||||
|
Scrape struct {
|
||||||
|
TimeoutMargin string `yaml:"timeout-margin"`
|
||||||
|
} `yaml:"scrape"`
|
||||||
|
Telemetry struct {
|
||||||
|
Path string `yaml:"path"`
|
||||||
|
} `yaml:"telemetry"`
|
||||||
|
Web struct {
|
||||||
|
DisableExporterMetrics bool `yaml:"disable-exporter-metrics"`
|
||||||
|
ListenAddresses any `yaml:"listen-address"`
|
||||||
|
Config struct {
|
||||||
|
File string `yaml:"file"`
|
||||||
|
} `yaml:"config"`
|
||||||
|
} `yaml:"web"`
|
||||||
|
}
|
||||||
|
|
||||||
type getFlagger interface {
|
type getFlagger interface {
|
||||||
GetFlag(name string) *kingpin.FlagClause
|
GetFlag(name string) *kingpin.FlagClause
|
||||||
}
|
}
|
||||||
@@ -80,24 +116,37 @@ func ParseConfigFile(args []string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewConfigFileResolver returns a Resolver structure.
|
// NewConfigFileResolver returns a Resolver structure.
|
||||||
func NewConfigFileResolver(file string) (*Resolver, error) {
|
func NewConfigFileResolver(filePath string) (*Resolver, error) {
|
||||||
flags := map[string]string{}
|
flags := map[string]string{}
|
||||||
|
|
||||||
var (
|
file, err := os.Open(filePath)
|
||||||
err error
|
|
||||||
fileBytes []byte
|
|
||||||
)
|
|
||||||
|
|
||||||
fileBytes, err = readFromFile(file)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to open configuration file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_ = file.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
var configFileStructure configFile
|
||||||
|
|
||||||
|
decoder := yaml.NewDecoder(file)
|
||||||
|
decoder.KnownFields(true)
|
||||||
|
|
||||||
|
if err = decoder.Decode(&configFileStructure); err != nil {
|
||||||
|
return nil, fmt.Errorf("configuration file validation error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = file.Seek(0, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to rewind file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawValues map[string]interface{}
|
var rawValues map[string]interface{}
|
||||||
|
|
||||||
err = yaml.Unmarshal(fileBytes, &rawValues)
|
decoder = yaml.NewDecoder(file)
|
||||||
if err != nil {
|
if err = decoder.Decode(&rawValues); err != nil {
|
||||||
return nil, fmt.Errorf("failed to unmarshal configuration file: %w", err)
|
return nil, fmt.Errorf("failed to parse configuration file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flatten nested YAML values
|
// Flatten nested YAML values
|
||||||
@@ -111,23 +160,9 @@ func NewConfigFileResolver(file string) (*Resolver, error) {
|
|||||||
return &Resolver{flags: flags}, nil
|
return &Resolver{flags: flags}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readFromFile(file string) ([]byte, error) {
|
|
||||||
if _, err := os.Stat(file); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read configuration file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileBytes, err := os.ReadFile(file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read configuration file: %w", 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)
|
if f := v.GetFlag(name); f != nil {
|
||||||
if f != nil {
|
|
||||||
f.Default(value)
|
f.Default(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,26 +79,26 @@ 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:"disk_drive"`
|
DiskDrive diskdrive.Config `yaml:"diskdrive"`
|
||||||
DNS dns.Config `yaml:"dns"`
|
DNS dns.Config `yaml:"dns"`
|
||||||
Exchange exchange.Config `yaml:"exchange"`
|
Exchange exchange.Config `yaml:"exchange"`
|
||||||
Filetime filetime.Config `yaml:"filetime"`
|
Filetime filetime.Config `yaml:"filetime"`
|
||||||
Fsrmquota fsrmquota.Config `yaml:"fsrmquota"`
|
Fsrmquota fsrmquota.Config `yaml:"fsrmquota"`
|
||||||
HyperV hyperv.Config `yaml:"hyper_v"`
|
HyperV hyperv.Config `yaml:"hyperv"`
|
||||||
IIS iis.Config `yaml:"iis"`
|
IIS iis.Config `yaml:"iis"`
|
||||||
License license.Config `yaml:"license"`
|
License license.Config `yaml:"license"`
|
||||||
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
||||||
Logon logon.Config `yaml:"logon"`
|
Logon logon.Config `yaml:"logon"`
|
||||||
Memory memory.Config `yaml:"memory"`
|
Memory memory.Config `yaml:"memory"`
|
||||||
MSCluster mscluster.Config `yaml:"ms_cluster"`
|
MSCluster mscluster.Config `yaml:"mscluster"`
|
||||||
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"`
|
||||||
NetFramework netframework.Config `yaml:"net_framework"`
|
NetFramework netframework.Config `yaml:"netframework"`
|
||||||
Nps nps.Config `yaml:"nps"`
|
Nps nps.Config `yaml:"nps"`
|
||||||
OS os.Config `yaml:"os"`
|
OS os.Config `yaml:"os"`
|
||||||
Paging pagefile.Config `yaml:"paging"`
|
Paging pagefile.Config `yaml:"paging"`
|
||||||
PerformanceCounter performancecounter.Config `yaml:"performance_counter"`
|
PerformanceCounter performancecounter.Config `yaml:"performancecounter"`
|
||||||
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
|
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
|
||||||
Printer printer.Config `yaml:"printer"`
|
Printer printer.Config `yaml:"printer"`
|
||||||
Process process.Config `yaml:"process"`
|
Process process.Config `yaml:"process"`
|
||||||
@@ -112,7 +112,7 @@ type Config struct {
|
|||||||
TCP tcp.Config `yaml:"tcp"`
|
TCP tcp.Config `yaml:"tcp"`
|
||||||
TerminalServices terminal_services.Config `yaml:"terminal_services"`
|
TerminalServices terminal_services.Config `yaml:"terminal_services"`
|
||||||
Textfile textfile.Config `yaml:"textfile"`
|
Textfile textfile.Config `yaml:"textfile"`
|
||||||
ThermalZone thermalzone.Config `yaml:"thermal_zone"`
|
ThermalZone thermalzone.Config `yaml:"thermalzone"`
|
||||||
Time time.Config `yaml:"time"`
|
Time time.Config `yaml:"time"`
|
||||||
UDP udp.Config `yaml:"udp"`
|
UDP udp.Config `yaml:"udp"`
|
||||||
Update update.Config `yaml:"update"`
|
Update update.Config `yaml:"update"`
|
||||||
|
|||||||
Reference in New Issue
Block a user