Merge pull request #1170 from breed808/include_exclude

feat!: Deprecate whitelist/blacklist flags
This commit is contained in:
Ben Reedy
2023-04-19 09:15:30 +10:00
committed by GitHub
17 changed files with 465 additions and 161 deletions

View File

@@ -104,7 +104,7 @@ Name | Description
`LISTEN_PORT` | The port to bind to. Defaults to 9182. `LISTEN_PORT` | The port to bind to. Defaults to 9182.
`METRICS_PATH` | The path at which to serve metrics. Defaults to `/metrics` `METRICS_PATH` | The path at which to serve metrics. Defaults to `/metrics`
`TEXTFILE_DIR` | As the `--collector.textfile.directory` flag, provide a directory to read text files with metrics from `TEXTFILE_DIR` | As the `--collector.textfile.directory` flag, provide a directory to read text files with metrics from
`REMOTE_ADDR` | Allows setting comma separated remote IP addresses for the Windows Firewall exception (whitelist). Defaults to an empty string (any remote address). `REMOTE_ADDR` | Allows setting comma separated remote IP addresses for the Windows Firewall exception (allow list). Defaults to an empty string (any remote address).
`EXTRA_FLAGS` | Allows passing full CLI flags. Defaults to an empty string. `EXTRA_FLAGS` | Allows passing full CLI flags. Defaults to an empty string.
Parameters are sent to the installer via `msiexec`. Example invocations: Parameters are sent to the installer via `msiexec`. Example invocations:
@@ -150,7 +150,7 @@ The prometheus metrics will be exposed on [localhost:9182](http://localhost:9182
### Enable only process collector and specify a custom query ### Enable only process collector and specify a custom query
.\windows_exporter.exe --collectors.enabled "process" --collector.process.whitelist="firefox.+" .\windows_exporter.exe --collectors.enabled "process" --collector.process.include="firefox.+"
When there are multiple processes with the same name, WMI represents those after the first instance as `process-name#index`. So to get them all, rather than just the first one, the [regular expression](https://en.wikipedia.org/wiki/Regular_expression) must use `.+`. See [process](docs/collector.process.md) for more information. When there are multiple processes with the same name, WMI represents those after the first instance as `process-name#index`. So to get them all, rather than just the first one, the [regular expression](https://en.wikipedia.org/wiki/Regular_expression) must use `.+`. See [process](docs/collector.process.md) for more information.

View File

@@ -4,6 +4,7 @@
package collector package collector
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
@@ -14,17 +15,32 @@ import (
) )
const ( const (
FlagISSSiteBlacklist = "collector.iis.site-blacklist" FlagIISSiteOldExclude = "collector.iis.site-blacklist"
FlagISSSiteWhitelist = "collector.iis.site-whitelist" FlagIISSiteOldInclude = "collector.iis.site-whitelist"
FlagISSAppBlacklist = "collector.iis.app-blacklist" FlagIISAppOldExclude = "collector.iis.app-blacklist"
FlagISSAppWhitelist = "collector.iis.app-whitelist" FlagIISAppOldInclude = "collector.iis.app-whitelist"
FlagIISSiteExclude = "collector.iis.site-exclude"
FlagIISSiteInclude = "collector.iis.site-include"
FlagIISAppExclude = "collector.iis.app-exclude"
FlagIISAppInclude = "collector.iis.app-include"
) )
var ( var (
siteWhitelist *string oldSiteInclude *string
siteBlacklist *string oldSiteExclude *string
appWhitelist *string oldAppInclude *string
appBlacklist *string oldAppExclude *string
siteInclude *string
siteExclude *string
appInclude *string
appExclude *string
siteIncludeSet bool
siteExcludeSet bool
appIncludeSet bool
appExcludeSet bool
) )
type simple_version struct { type simple_version struct {
@@ -89,8 +105,8 @@ type IISCollector struct {
TotalNotFoundErrors *prometheus.Desc TotalNotFoundErrors *prometheus.Desc
TotalRejectedAsyncIORequests *prometheus.Desc TotalRejectedAsyncIORequests *prometheus.Desc
siteWhitelistPattern *regexp.Regexp siteIncludePattern *regexp.Regexp
siteBlacklistPattern *regexp.Regexp siteExcludePattern *regexp.Regexp
// APP_POOL_WAS // APP_POOL_WAS
CurrentApplicationPoolState *prometheus.Desc CurrentApplicationPoolState *prometheus.Desc
@@ -192,29 +208,94 @@ type IISCollector struct {
ServiceCache_OutputCacheFlushedItemsTotal *prometheus.Desc ServiceCache_OutputCacheFlushedItemsTotal *prometheus.Desc
ServiceCache_OutputCacheFlushesTotal *prometheus.Desc ServiceCache_OutputCacheFlushesTotal *prometheus.Desc
appWhitelistPattern *regexp.Regexp appIncludePattern *regexp.Regexp
appBlacklistPattern *regexp.Regexp appExcludePattern *regexp.Regexp
iis_version simple_version iis_version simple_version
} }
func newIISCollectorFlags(app *kingpin.Application) { func newIISCollectorFlags(app *kingpin.Application) {
siteWhitelist = kingpin.Flag(FlagISSSiteWhitelist, "Regexp of sites to whitelist. Site name must both match whitelist and not match blacklist to be included.").Default(".+").String() oldSiteInclude = app.Flag(FlagIISSiteOldInclude, "DEPRECATED: Use --collector.iis.site-include").Default(".+").Hidden().String()
siteBlacklist = kingpin.Flag(FlagISSSiteBlacklist, "Regexp of sites to blacklist. Site name must both match whitelist and not match blacklist to be included.").String() oldSiteExclude = app.Flag(FlagIISSiteOldExclude, "DEPRECATED: Use --collector.iis.site-exclude").Hidden().String()
appWhitelist = kingpin.Flag(FlagISSAppWhitelist, "Regexp of apps to whitelist. App name must both match whitelist and not match blacklist to be included.").Default(".+").String() oldAppInclude = app.Flag(FlagIISAppOldInclude, "DEPRECATED: Use --collector.iis.app-include").Hidden().String()
appBlacklist = kingpin.Flag(FlagISSAppBlacklist, "Regexp of apps to blacklist. App name must both match whitelist and not match blacklist to be included.").String() oldAppExclude = app.Flag(FlagIISAppOldExclude, "DEPRECATED: Use --collector.iis.app-exclude").Hidden().String()
siteInclude = app.Flag(
FlagIISSiteInclude,
"Regexp of sites to include. Site name must both match include and not match exclude to be included.",
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
siteIncludeSet = true
return nil
}).String()
siteExclude = app.Flag(
FlagIISSiteExclude,
"Regexp of sites to exclude. Site name must both match include and not match exclude to be included.",
).Default("").PreAction(func(c *kingpin.ParseContext) error {
siteExcludeSet = true
return nil
}).String()
appInclude = app.Flag(
FlagIISAppInclude,
"Regexp of apps to include. App name must both match include and not match exclude to be included.",
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
appIncludeSet = true
return nil
}).String()
appExclude = app.Flag(
FlagIISAppExclude,
"Regexp of apps to include. App name must both match include and not match exclude to be included.",
).Default("").PreAction(func(c *kingpin.ParseContext) error {
siteExcludeSet = true
return nil
}).String()
} }
func newIISCollector() (Collector, error) { func newIISCollector() (Collector, error) {
const subsystem = "iis" if *oldSiteExclude != "" {
if !siteExcludeSet {
log.Warnln("msg", "--collector.iis.site-blacklist is DEPRECATED and will be removed in a future release, use --collector.iis.site-exclude")
*siteExclude = *oldSiteExclude
} else {
return nil, errors.New("--collector.iis.site-blacklist and --collector.iis.site-exclude are mutually exclusive")
}
}
if *oldSiteInclude != "" {
if !siteIncludeSet {
log.Warnln("msg", "--collector.iis.site-whitelist is DEPRECATED and will be removed in a future release, use --collector.iis.site-include")
*siteInclude = *oldSiteInclude
} else {
return nil, errors.New("--collector.iis.site-whitelist and --collector.iis.site-include are mutually exclusive")
}
}
if *oldAppExclude != "" {
if !appExcludeSet {
log.Warnln("msg", "--collector.iis.app-blacklist is DEPRECATED and will be removed in a future release, use --collector.iis.app-exclude")
*appExclude = *oldAppExclude
} else {
return nil, errors.New("--collector.iis.app-blacklist and --collector.iis.app-exclude are mutually exclusive")
}
}
if *oldAppInclude != "" {
if !appIncludeSet {
log.Warnln("msg", "--collector.iis.app-whitelist is DEPRECATED and will be removed in a future release, use --collector.iis.app-include")
*appInclude = *oldAppInclude
} else {
return nil, errors.New("--collector.iis.app-whitelist and --collector.iis.app-include are mutually exclusive")
}
}
const subsystem = "iis"
return &IISCollector{ return &IISCollector{
iis_version: getIISVersion(), iis_version: getIISVersion(),
siteWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteWhitelist)), siteIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteInclude)),
siteBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteBlacklist)), siteExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteExclude)),
appWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appWhitelist)), appIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appInclude)),
appBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appBlacklist)), appExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *appExclude)),
// Web Service // Web Service
CurrentAnonymousUsers: prometheus.NewDesc( CurrentAnonymousUsers: prometheus.NewDesc(
@@ -903,7 +984,7 @@ func (c *IISCollector) collectWebService(ctx *ScrapeContext, ch chan<- prometheu
} }
for _, app := range WebService { for _, app := range WebService {
if app.Name == "_Total" || c.siteBlacklistPattern.MatchString(app.Name) || !c.siteWhitelistPattern.MatchString(app.Name) { if app.Name == "_Total" || c.siteExcludePattern.MatchString(app.Name) || !c.siteIncludePattern.MatchString(app.Name) {
continue continue
} }
@@ -1188,8 +1269,8 @@ func (c *IISCollector) collectAPP_POOL_WAS(ctx *ScrapeContext, ch chan<- prometh
for _, app := range APP_POOL_WAS { for _, app := range APP_POOL_WAS {
if app.Name == "_Total" || if app.Name == "_Total" ||
c.appBlacklistPattern.MatchString(app.Name) || c.appExcludePattern.MatchString(app.Name) ||
!c.appWhitelistPattern.MatchString(app.Name) { !c.appIncludePattern.MatchString(app.Name) {
continue continue
} }
@@ -1366,8 +1447,8 @@ func (c *IISCollector) collectW3SVC_W3WP(ctx *ScrapeContext, ch chan<- prometheu
pid := workerProcessNameExtractor.ReplaceAllString(app.Name, "$1") pid := workerProcessNameExtractor.ReplaceAllString(app.Name, "$1")
name := workerProcessNameExtractor.ReplaceAllString(app.Name, "$2") name := workerProcessNameExtractor.ReplaceAllString(app.Name, "$2")
if name == "" || name == "_Total" || if name == "" || name == "_Total" ||
c.appBlacklistPattern.MatchString(name) || c.appExcludePattern.MatchString(name) ||
!c.appWhitelistPattern.MatchString(name) { !c.appIncludePattern.MatchString(name) {
continue continue
} }
@@ -1618,8 +1699,8 @@ func (c *IISCollector) collectW3SVC_W3WP(ctx *ScrapeContext, ch chan<- prometheu
pid := workerProcessNameExtractor.ReplaceAllString(app.Name, "$1") pid := workerProcessNameExtractor.ReplaceAllString(app.Name, "$1")
name := workerProcessNameExtractor.ReplaceAllString(app.Name, "$2") name := workerProcessNameExtractor.ReplaceAllString(app.Name, "$2")
if name == "" || name == "_Total" || if name == "" || name == "_Total" ||
c.appBlacklistPattern.MatchString(name) || c.appExcludePattern.MatchString(name) ||
!c.appWhitelistPattern.MatchString(name) { !c.appIncludePattern.MatchString(name) {
continue continue
} }

View File

@@ -4,6 +4,7 @@
package collector package collector
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
@@ -13,13 +14,22 @@ import (
) )
const ( const (
FlagLogicalDiskVolumeBlacklist = "collector.logical_disk.volume-blacklist" FlagLogicalDiskVolumeOldExclude = "collector.logical_disk.volume-blacklist"
FlagLogicalDiskVolumeWhitelist = "collector.logical_disk.volume-whitelist" FlagLogicalDiskVolumeOldInclude = "collector.logical_disk.volume-whitelist"
FlagLogicalDiskVolumeExclude = "collector.logical_disk.volume-exclude"
FlagLogicalDiskVolumeInclude = "collector.logical_disk.volume-include"
) )
var ( var (
volumeWhitelist *string volumeOldInclude *string
volumeBlacklist *string volumeOldExclude *string
volumeInclude *string
volumeExclude *string
volumeIncludeSet bool
volumeExcludeSet bool
) )
// A LogicalDiskCollector is a Prometheus collector for perflib logicalDisk metrics // A LogicalDiskCollector is a Prometheus collector for perflib logicalDisk metrics
@@ -41,24 +51,57 @@ type LogicalDiskCollector struct {
WriteLatency *prometheus.Desc WriteLatency *prometheus.Desc
ReadWriteLatency *prometheus.Desc ReadWriteLatency *prometheus.Desc
volumeWhitelistPattern *regexp.Regexp volumeIncludePattern *regexp.Regexp
volumeBlacklistPattern *regexp.Regexp volumeExcludePattern *regexp.Regexp
} }
// newLogicalDiskCollectorFlags ... // newLogicalDiskCollectorFlags ...
func newLogicalDiskCollectorFlags(app *kingpin.Application) { func newLogicalDiskCollectorFlags(app *kingpin.Application) {
volumeWhitelist = app.Flag( volumeInclude = app.Flag(
FlagLogicalDiskVolumeWhitelist, FlagLogicalDiskVolumeInclude,
"Regexp of volumes to whitelist. Volume name must both match whitelist and not match blacklist to be included.", "Regexp of volumes to include. Volume name must both match include and not match exclude to be included.",
).Default(".+").String() ).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
volumeBlacklist = app.Flag( volumeIncludeSet = true
FlagLogicalDiskVolumeBlacklist, return nil
"Regexp of volumes to blacklist. Volume name must both match whitelist and not match blacklist to be included.", }).String()
).Default("").String()
volumeExclude = app.Flag(
FlagLogicalDiskVolumeExclude,
"Regexp of volumes to exclude. Volume name must both match include and not match exclude to be included.",
).Default("").PreAction(func(c *kingpin.ParseContext) error {
volumeExcludeSet = true
return nil
}).String()
volumeOldInclude = app.Flag(
FlagLogicalDiskVolumeOldInclude,
"DEPRECATED: Use --collector.logical_disk.volume-include",
).Hidden().String()
volumeOldExclude = app.Flag(
FlagLogicalDiskVolumeOldExclude,
"DEPRECATED: Use --collector.logical_disk.volume-exclude",
).Hidden().String()
} }
// newLogicalDiskCollector ... // newLogicalDiskCollector ...
func newLogicalDiskCollector() (Collector, error) { func newLogicalDiskCollector() (Collector, error) {
if *volumeOldExclude != "" {
if !volumeExcludeSet {
log.Warnln("msg", "--collector.logical_disk.volume-blacklist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-exclude")
*volumeExclude = *volumeOldExclude
} else {
return nil, errors.New("--collector.logical_disk.volume-blacklist and --collector.logical_disk.volume-exclude are mutually exclusive")
}
}
if *volumeOldInclude != "" {
if !volumeIncludeSet {
log.Warnln("msg", "--collector.logical_disk.volume-whitelist is DEPRECATED and will be removed in a future release, use --collector.logical_disk.volume-include")
*volumeInclude = *volumeOldInclude
} else {
return nil, errors.New("--collector.logical_disk.volume-whitelist and --collector.logical_disk.volume-include are mutually exclusive")
}
}
const subsystem = "logical_disk" const subsystem = "logical_disk"
return &LogicalDiskCollector{ return &LogicalDiskCollector{
@@ -174,8 +217,8 @@ func newLogicalDiskCollector() (Collector, error) {
nil, nil,
), ),
volumeWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeWhitelist)), volumeIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeInclude)),
volumeBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeBlacklist)), volumeExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeExclude)),
}, nil }, nil
} }
@@ -220,8 +263,8 @@ func (c *LogicalDiskCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.
for _, volume := range dst { for _, volume := range dst {
if volume.Name == "_Total" || if volume.Name == "_Total" ||
c.volumeBlacklistPattern.MatchString(volume.Name) || c.volumeExcludePattern.MatchString(volume.Name) ||
!c.volumeWhitelistPattern.MatchString(volume.Name) { !c.volumeIncludePattern.MatchString(volume.Name) {
continue continue
} }

View File

@@ -6,8 +6,8 @@ import (
func BenchmarkLogicalDiskCollector(b *testing.B) { func BenchmarkLogicalDiskCollector(b *testing.B) {
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all disks. // Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all disks.
localVolumeWhitelist := ".+" localVolumeInclude := ".+"
volumeWhitelist = &localVolumeWhitelist volumeInclude = &localVolumeInclude
benchmarkCollector(b, "logical_disk", newLogicalDiskCollector) benchmarkCollector(b, "logical_disk", newLogicalDiskCollector)
} }

View File

@@ -4,6 +4,7 @@
package collector package collector
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
@@ -13,13 +14,23 @@ import (
) )
const ( const (
FlagNicBlacklist = "collector.net.nic-blacklist" FlagNicOldExclude = "collector.net.nic-blacklist"
FlagNicWhitelist = "collector.net.nic-whitelist" FlagNicOldInclude = "collector.net.nic-whitelist"
FlagNicExclude = "collector.net.nic-exclude"
FlagNicInclude = "collector.net.nic-include"
) )
var ( var (
nicWhitelist *string nicOldInclude *string
nicBlacklist *string nicOldExclude *string
nicInclude *string
nicExclude *string
nicIncludeSet bool
nicExcludeSet bool
nicNameToUnderscore = regexp.MustCompile("[^a-zA-Z0-9]") nicNameToUnderscore = regexp.MustCompile("[^a-zA-Z0-9]")
) )
@@ -39,24 +50,58 @@ type NetworkCollector struct {
PacketsSentTotal *prometheus.Desc PacketsSentTotal *prometheus.Desc
CurrentBandwidth *prometheus.Desc CurrentBandwidth *prometheus.Desc
nicWhitelistPattern *regexp.Regexp nicIncludePattern *regexp.Regexp
nicBlacklistPattern *regexp.Regexp nicExcludePattern *regexp.Regexp
} }
// newNetworkCollectorFlags ... // newNetworkCollectorFlags ...
func newNetworkCollectorFlags(app *kingpin.Application) { func newNetworkCollectorFlags(app *kingpin.Application) {
nicWhitelist = app.Flag( nicInclude = app.Flag(
FlagNicWhitelist, FlagNicInclude,
"Regexp of NIC:s to whitelist. NIC name must both match whitelist and not match blacklist to be included.", "Regexp of NIC:s to include. NIC name must both match include and not match exclude to be included.",
).Default(".+").String() ).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
nicBlacklist = app.Flag( nicIncludeSet = true
FlagNicBlacklist, return nil
"Regexp of NIC:s to blacklist. NIC name must both match whitelist and not match blacklist to be included.", }).String()
).Default("").String()
nicExclude = app.Flag(
FlagNicExclude,
"Regexp of NIC:s to exclude. NIC name must both match include and not match exclude to be included.",
).Default("").PreAction(func(c *kingpin.ParseContext) error {
nicExcludeSet = true
return nil
}).String()
nicOldInclude = app.Flag(
FlagNicOldInclude,
"DEPRECATED: Use --collector.net.nic-include",
).Hidden().String()
nicOldExclude = app.Flag(
FlagNicOldExclude,
"DEPRECATED: Use --collector.net.nic-exclude",
).Hidden().String()
} }
// newNetworkCollector ... // newNetworkCollector ...
func newNetworkCollector() (Collector, error) { func newNetworkCollector() (Collector, error) {
if *nicOldExclude != "" {
if !nicExcludeSet {
log.Warnln("msg", "--collector.net.nic-blacklist is DEPRECATED and will be removed in a future release, use --collector.net.nic-exclude")
*nicExclude = *nicOldExclude
} else {
return nil, errors.New("--collector.net.nic-blacklist and --collector.net.nic-exclude are mutually exclusive")
}
}
if *nicOldInclude != "" {
if !nicIncludeSet {
log.Warnln("msg", "--collector.net.nic-whitelist is DEPRECATED and will be removed in a future release, use --collector.net.nic-include")
*nicInclude = *nicOldInclude
} else {
return nil, errors.New("--collector.net.nic-whitelist and --collector.net.nic-include are mutually exclusive")
}
}
const subsystem = "net" const subsystem = "net"
return &NetworkCollector{ return &NetworkCollector{
@@ -139,8 +184,8 @@ func newNetworkCollector() (Collector, error) {
nil, nil,
), ),
nicWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicWhitelist)), nicIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicInclude)),
nicBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicBlacklist)), nicExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *nicExclude)),
}, nil }, nil
} }
@@ -187,8 +232,8 @@ func (c *NetworkCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
} }
for _, nic := range dst { for _, nic := range dst {
if c.nicBlacklistPattern.MatchString(nic.Name) || if c.nicExcludePattern.MatchString(nic.Name) ||
!c.nicWhitelistPattern.MatchString(nic.Name) { !c.nicIncludePattern.MatchString(nic.Name) {
continue continue
} }

View File

@@ -20,8 +20,8 @@ func TestNetworkToInstanceName(t *testing.T) {
} }
func BenchmarkNetCollector(b *testing.B) { func BenchmarkNetCollector(b *testing.B) {
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all interfaces. // Include is not set in testing context (kingpin flags not parsed), causing the collector to skip all interfaces.
localNicWhitelist := ".+" localNicInclude := ".+"
nicWhitelist = &localNicWhitelist nicInclude = &localNicInclude
benchmarkCollector(b, "net", newNetworkCollector) benchmarkCollector(b, "net", newNetworkCollector)
} }

View File

@@ -4,6 +4,7 @@
package collector package collector
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
"strconv" "strconv"
@@ -16,13 +17,22 @@ import (
) )
const ( const (
FlagProcessBlacklist = "collector.process.blacklist" FlagProcessOldExclude = "collector.process.blacklist"
FlagProcessWhitelist = "collector.process.whitelist" FlagProcessOldInclude = "collector.process.whitelist"
FlagProcessExclude = "collector.process.exclude"
FlagProcessInclude = "collector.process.include"
) )
var ( var (
processWhitelist *string processOldInclude *string
processBlacklist *string processOldExclude *string
processInclude *string
processExclude *string
processIncludeSet bool
processExcludeSet bool
) )
type processCollector struct { type processCollector struct {
@@ -42,27 +52,60 @@ type processCollector struct {
WorkingSetPeak *prometheus.Desc WorkingSetPeak *prometheus.Desc
WorkingSet *prometheus.Desc WorkingSet *prometheus.Desc
processWhitelistPattern *regexp.Regexp processIncludePattern *regexp.Regexp
processBlacklistPattern *regexp.Regexp processExcludePattern *regexp.Regexp
} }
// newProcessCollectorFlags ... // newProcessCollectorFlags ...
func newProcessCollectorFlags(app *kingpin.Application) { func newProcessCollectorFlags(app *kingpin.Application) {
processWhitelist = app.Flag( processInclude = app.Flag(
FlagProcessWhitelist, FlagProcessInclude,
"Regexp of processes to include. Process name must both match whitelist and not match blacklist to be included.", "Regexp of processes to include. Process name must both match include and not match exclude to be included.",
).Default(".*").String() ).Default(".*").PreAction(func(c *kingpin.ParseContext) error {
processBlacklist = app.Flag( processIncludeSet = true
FlagProcessBlacklist, return nil
"Regexp of processes to exclude. Process name must both match whitelist and not match blacklist to be included.", }).String()
).Default("").String()
processExclude = app.Flag(
FlagProcessExclude,
"Regexp of processes to exclude. Process name must both match include and not match exclude to be included.",
).Default("").PreAction(func(c *kingpin.ParseContext) error {
processExcludeSet = true
return nil
}).String()
processOldInclude = app.Flag(
FlagProcessOldInclude,
"DEPRECATED: Use --collector.process.include",
).Hidden().String()
processOldExclude = app.Flag(
FlagProcessOldExclude,
"DEPRECATED: Use --collector.process.exclude",
).Hidden().String()
} }
// NewProcessCollector ... // NewProcessCollector ...
func newProcessCollector() (Collector, error) { func newProcessCollector() (Collector, error) {
const subsystem = "process" const subsystem = "process"
if *processWhitelist == ".*" && *processBlacklist == "" { if *processOldExclude != "" {
if !processExcludeSet {
log.Warnln("msg", "--collector.process.blacklist is DEPRECATED and will be removed in a future release, use --collector.process.exclude")
*processExclude = *processOldExclude
} else {
return nil, errors.New("--collector.process.blacklist and --collector.process.exclude are mutually exclusive")
}
}
if *processOldInclude != "" {
if !processIncludeSet {
log.Warnln("msg", "--collector.process.whitelist is DEPRECATED and will be removed in a future release, use --collector.process.include")
*processInclude = *processOldInclude
} else {
return nil, errors.New("--collector.process.whitelist and --collector.process.include are mutually exclusive")
}
}
if *processInclude == ".*" && *processExclude == "" {
log.Warn("No filters specified for process collector. This will generate a very large number of metrics!") log.Warn("No filters specified for process collector. This will generate a very large number of metrics!")
} }
@@ -157,8 +200,8 @@ func newProcessCollector() (Collector, error) {
[]string{"process", "process_id", "creating_process_id"}, []string{"process", "process_id", "creating_process_id"},
nil, nil,
), ),
processWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processWhitelist)), processIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processInclude)),
processBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processBlacklist)), processExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *processExclude)),
}, nil }, nil
} }
@@ -214,8 +257,8 @@ func (c *processCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metr
for _, process := range data { for _, process := range data {
if process.Name == "_Total" || if process.Name == "_Total" ||
c.processBlacklistPattern.MatchString(process.Name) || c.processExcludePattern.MatchString(process.Name) ||
!c.processWhitelistPattern.MatchString(process.Name) { !c.processIncludePattern.MatchString(process.Name) {
continue continue
} }
// Duplicate processes are suffixed # and an index number. Remove those. // Duplicate processes are suffixed # and an index number. Remove those.

View File

@@ -5,9 +5,9 @@ import (
) )
func BenchmarkProcessCollector(b *testing.B) { func BenchmarkProcessCollector(b *testing.B) {
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all processes. // Include is not set in testing context (kingpin flags not parsed), causing the collector to skip all processes.
localProcessWhitelist := ".+" localProcessInclude := ".+"
processWhitelist = &localProcessWhitelist processInclude = &localProcessInclude
// No context name required as collector source is WMI // No context name required as collector source is WMI
benchmarkCollector(b, "", newProcessCollector) benchmarkCollector(b, "", newProcessCollector)

View File

@@ -4,6 +4,7 @@
package collector package collector
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
"runtime" "runtime"
@@ -17,13 +18,22 @@ import (
) )
const ( const (
FlagScheduledTaskBlacklist = "collector.scheduled_task.blacklist" FlagScheduledTaskOldExclude = "collector.scheduled_task.blacklist"
FlagScheduledTaskWhitelist = "collector.scheduled_task.whitelist" FlagScheduledTaskOldInclude = "collector.scheduled_task.whitelist"
FlagScheduledTaskExclude = "collector.scheduled_task.exclude"
FlagScheduledTaskInclude = "collector.scheduled_task.include"
) )
var ( var (
taskWhitelist *string taskOldExclude *string
taskBlacklist *string taskOldInclude *string
taskExclude *string
taskInclude *string
taskIncludeSet bool
taskExcludeSet bool
) )
type ScheduledTaskCollector struct { type ScheduledTaskCollector struct {
@@ -31,8 +41,8 @@ type ScheduledTaskCollector struct {
MissedRuns *prometheus.Desc MissedRuns *prometheus.Desc
State *prometheus.Desc State *prometheus.Desc
taskWhitelistPattern *regexp.Regexp taskIncludePattern *regexp.Regexp
taskBlacklistPattern *regexp.Regexp taskExcludePattern *regexp.Regexp
} }
// TaskState ... // TaskState ...
@@ -64,18 +74,51 @@ type ScheduledTasks []ScheduledTask
// newScheduledTask ... // newScheduledTask ...
func newScheduledTaskFlags(app *kingpin.Application) { func newScheduledTaskFlags(app *kingpin.Application) {
taskWhitelist = app.Flag( taskInclude = app.Flag(
FlagScheduledTaskWhitelist, FlagScheduledTaskInclude,
"Regexp of tasks to whitelist. Task path must both match whitelist and not match blacklist to be included.", "Regexp of tasks to include. Task path must both match include and not match exclude to be included.",
).Default(".+").String() ).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
taskBlacklist = app.Flag( taskIncludeSet = true
FlagScheduledTaskBlacklist, return nil
"Regexp of tasks to blacklist. Task path must both match whitelist and not match blacklist to be included.", }).String()
).String()
taskExclude = app.Flag(
FlagScheduledTaskExclude,
"Regexp of tasks to exclude. Task path must both match include and not match exclude to be included.",
).Default("").PreAction(func(c *kingpin.ParseContext) error {
taskExcludeSet = true
return nil
}).String()
taskOldInclude = app.Flag(
FlagScheduledTaskOldInclude,
"DEPRECATED: Use --collector.scheduled_task.include",
).Hidden().String()
taskOldExclude = app.Flag(
FlagScheduledTaskOldExclude,
"DEPRECATED: Use --collector.scheduled_task.exclude",
).Hidden().String()
} }
// newScheduledTask ... // newScheduledTask ...
func newScheduledTask() (Collector, error) { func newScheduledTask() (Collector, error) {
if *taskOldExclude != "" {
if !taskExcludeSet {
log.Warnln("msg", "--collector.scheduled_task.blacklist is DEPRECATED and will be removed in a future release, use --collector.scheduled_task.exclude")
*taskExclude = *taskOldExclude
} else {
return nil, errors.New("--collector.scheduled_task.blacklist and --collector.scheduled_task.exclude are mutually exclusive")
}
}
if *taskOldInclude != "" {
if !taskIncludeSet {
log.Warnln("msg", "--collector.scheduled_task.whitelist is DEPRECATED and will be removed in a future release, use --collector.scheduled_task.include")
*taskInclude = *taskOldInclude
} else {
return nil, errors.New("--collector.scheduled_task.whitelist and --collector.scheduled_task.include are mutually exclusive")
}
}
const subsystem = "scheduled_task" const subsystem = "scheduled_task"
runtime.LockOSThread() runtime.LockOSThread()
@@ -112,8 +155,8 @@ func newScheduledTask() (Collector, error) {
nil, nil,
), ),
taskWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskWhitelist)), taskIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskInclude)),
taskBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskBlacklist)), taskExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *taskExclude)),
}, nil }, nil
} }
@@ -135,8 +178,8 @@ func (c *ScheduledTaskCollector) collect(ch chan<- prometheus.Metric) (*promethe
} }
for _, task := range scheduledTasks { for _, task := range scheduledTasks {
if c.taskBlacklistPattern.MatchString(task.Path) || if c.taskExcludePattern.MatchString(task.Path) ||
!c.taskWhitelistPattern.MatchString(task.Path) { !c.taskIncludePattern.MatchString(task.Path) {
continue continue
} }

View File

@@ -4,6 +4,7 @@
package collector package collector
import ( import (
"errors"
"fmt" "fmt"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/log" "github.com/prometheus-community/windows_exporter/log"
@@ -12,13 +13,22 @@ import (
) )
const ( const (
FlagSmtpServerBlacklist = "collector.smtp.server-blacklist" FlagSmtpServerOldExclude = "collector.smtp.server-blacklist"
FlagSmtpServerWhitelist = "collector.smtp.server-whitelist" FlagSmtpServerOldInclude = "collector.smtp.server-whitelist"
FlagSmtpServerExclude = "collector.smtp.server-exclude"
FlagSmtpServerInclude = "collector.smtp.server-include"
) )
var ( var (
serverWhitelist *string serverOldInclude *string
serverBlacklist *string serverOldExclude *string
serverInclude *string
serverExclude *string
serverIncludeSet bool
serverExcludeSet bool
) )
type SMTPCollector struct { type SMTPCollector struct {
@@ -65,19 +75,58 @@ type SMTPCollector struct {
RemoteRetryQueueLength *prometheus.Desc RemoteRetryQueueLength *prometheus.Desc
RoutingTableLookupsTotal *prometheus.Desc RoutingTableLookupsTotal *prometheus.Desc
serverWhitelistPattern *regexp.Regexp serverIncludePattern *regexp.Regexp
serverBlacklistPattern *regexp.Regexp serverExcludePattern *regexp.Regexp
} }
func newSMTPCollectorFlags(app *kingpin.Application) { func newSMTPCollectorFlags(app *kingpin.Application) {
serverWhitelist = app.Flag(FlagSmtpServerWhitelist, "Regexp of virtual servers to whitelist. Server name must both match whitelist and not match blacklist to be included.").Default(".+").String() serverInclude = app.Flag(
serverBlacklist = app.Flag(FlagSmtpServerBlacklist, "Regexp of virtual servers to blacklist. Server name must both match whitelist and not match blacklist to be included.").String() FlagSmtpServerInclude,
"Regexp of virtual servers to include. Server name must both match include and not match exclude to be included.",
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
serverIncludeSet = true
return nil
}).String()
serverExclude = app.Flag(
FlagSmtpServerExclude,
"Regexp of virtual servers to exclude. Server name must both match include and not match exclude to be included.",
).Default("").PreAction(func(c *kingpin.ParseContext) error {
serverExcludeSet = true
return nil
}).String()
serverOldInclude = app.Flag(
FlagSmtpServerOldInclude,
"DEPRECATED: Use --collector.smtp.server-include",
).Hidden().String()
serverOldExclude = app.Flag(
FlagSmtpServerOldExclude,
"DEPRECATED: Use --collector.smtp.server-exclude",
).Hidden().String()
} }
func newSMTPCollector() (Collector, error) { func newSMTPCollector() (Collector, error) {
log.Info("smtp collector is in an experimental state! Metrics for this collector have not been tested.") log.Info("smtp collector is in an experimental state! Metrics for this collector have not been tested.")
const subsystem = "smtp"
if *serverOldExclude != "" {
if !serverExcludeSet {
log.Warnln("msg", "--collector.smtp.server-blacklist is DEPRECATED and will be removed in a future release, use --collector.smtp.server-exclude")
*serverExclude = *serverOldExclude
} else {
return nil, errors.New("--collector.smtp.server-blacklist and --collector.smtp.server-exclude are mutually exclusive")
}
}
if *serverOldInclude != "" {
if !serverIncludeSet {
log.Warnln("msg", "--collector.smtp.server-whitelist is DEPRECATED and will be removed in a future release, use --collector.smtp.server-include")
*serverInclude = *serverOldInclude
} else {
return nil, errors.New("--collector.smtp.server-whitelist and --collector.smtp.server-include are mutually exclusive")
}
}
const subsystem = "smtp"
return &SMTPCollector{ return &SMTPCollector{
BadmailedMessagesBadPickupFileTotal: prometheus.NewDesc( BadmailedMessagesBadPickupFileTotal: prometheus.NewDesc(
prometheus.BuildFQName(Namespace, subsystem, "badmailed_messages_bad_pickup_file_total"), prometheus.BuildFQName(Namespace, subsystem, "badmailed_messages_bad_pickup_file_total"),
@@ -332,8 +381,8 @@ func newSMTPCollector() (Collector, error) {
nil, nil,
), ),
serverWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverWhitelist)), serverIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverInclude)),
serverBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverBlacklist)), serverExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *serverExclude)),
}, nil }, nil
} }
@@ -403,8 +452,8 @@ func (c *SMTPCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric)
for _, server := range dst { for _, server := range dst {
if server.Name == "_Total" || if server.Name == "_Total" ||
c.serverBlacklistPattern.MatchString(server.Name) || c.serverExcludePattern.MatchString(server.Name) ||
!c.serverWhitelistPattern.MatchString(server.Name) { !c.serverIncludePattern.MatchString(server.Name) {
continue continue
} }

View File

@@ -10,21 +10,21 @@ Enabled by default? | No
## Flags ## Flags
### `--collector.iis.site-whitelist` ### `--collector.iis.site-include`
If given, a site needs to match the whitelist regexp in order for the corresponding metrics to be reported. If given, a site needs to match the include regexp in order for the corresponding metrics to be reported.
### `--collector.iis.site-blacklist` ### `--collector.iis.site-exclude`
If given, a site needs to *not* match the blacklist regexp in order for the corresponding metrics to be reported. If given, a site needs to *not* match the exclude regexp in order for the corresponding metrics to be reported.
### `--collector.iis.app-whitelist` ### `--collector.iis.app-include`
If given, an application needs to match the whitelist regexp in order for the corresponding metrics to be reported. If given, an application needs to match the include regexp in order for the corresponding metrics to be reported.
### `--collector.iis.app-blacklist` ### `--collector.iis.app-exclude`
If given, an application needs to *not* match the blacklist regexp in order for the corresponding metrics to be reported. If given, an application needs to *not* match the exclude regexp in order for the corresponding metrics to be reported.
## Metrics ## Metrics

View File

@@ -11,13 +11,13 @@ Enabled by default? | Yes
## Flags ## Flags
### `--collector.logical_disk.volume-whitelist` ### `--collector.logical_disk.volume-include`
If given, a disk needs to match the whitelist regexp in order for the corresponding disk metrics to be reported If given, a disk needs to match the include regexp in order for the corresponding disk metrics to be reported
### `--collector.logical_disk.volume-blacklist` ### `--collector.logical_disk.volume-exclude`
If given, a disk needs to *not* match the blacklist regexp in order for the corresponding disk metrics to be reported If given, a disk needs to *not* match the exclude regexp in order for the corresponding disk metrics to be reported
## Metrics ## Metrics

View File

@@ -11,13 +11,13 @@ Enabled by default? | Yes
## Flags ## Flags
### `--collector.net.nic-whitelist` ### `--collector.net.nic-include`
If given, an interface name needs to match the whitelist regexp in order for the corresponding metrics to be reported If given, an interface name needs to match the include regexp in order for the corresponding metrics to be reported
### `--collector.net.nic-blacklist` ### `--collector.net.nic-exclude`
If given, an interface name needs to *not* match the blacklist regexp in order for the corresponding metrics to be reported If given, an interface name needs to *not* match the exclude regexp in order for the corresponding metrics to be reported
## Metrics ## Metrics

View File

@@ -11,35 +11,35 @@ Enabled by default? | No
## Flags ## Flags
### `--collector.process.whitelist` ### `--collector.process.include`
Regexp of processes to include. Process name must both match whitelist and not Regexp of processes to include. Process name must both match `include` and not
match blacklist to be included. Recommended to keep down number of returned match `exclude` to be included. Recommended to keep down number of returned
metrics. metrics.
### `--collector.process.blacklist` ### `--collector.process.exclude`
Regexp of processes to exclude. Process name must both match whitelist and not Regexp of processes to exclude. Process name must both match `include` and not
match blacklist to be included. Recommended to keep down number of returned match `exclude` to be included. Recommended to keep down number of returned
metrics. metrics.
### Example ### Example
To match all firefox processes: `--collector.process.whitelist="firefox.*"`. To match all firefox processes: `--collector.process.include="firefox.*"`.
Note that multiple processes with the same name will be disambiguated by Note that multiple processes with the same name will be disambiguated by
Windows by adding a number suffix, such as `firefox#2`. Your [regexp](https://en.wikipedia.org/wiki/Regular_expression) must take Windows by adding a number suffix, such as `firefox#2`. Your [regexp](https://en.wikipedia.org/wiki/Regular_expression) must take
these suffixes into consideration. these suffixes into consideration.
:warning: The regexp is case-sensitive, so `--collector.process.whitelist="FIREFOX.*"` will **NOT** match a process named `firefox` . :warning: The regexp is case-sensitive, so `--collector.process.include="FIREFOX.*"` will **NOT** match a process named `firefox` .
To specify multiple names, use the pipe `|` character: To specify multiple names, use the pipe `|` character:
``` ```
--collector.process.whitelist="(firefox|FIREFOX|chrome).*" --collector.process.include="(firefox|FIREFOX|chrome).*"
``` ```
This will match all processes named `firefox`, `FIREFOX` or `chrome` . This will match all processes named `firefox`, `FIREFOX` or `chrome` .
## IIS Worker processes ## IIS Worker processes
The process collector also queries the `root\\WebAdministration` WMI namespace to check for running IIS workers. If it successfully retrieves a list from this namespace, it will append the name of the worker's application pool to the corresponding process. Whitelist/blacklist matching occurs before this name is appended, so you don't have to take this name in consideration when writing your expression. The process collector also queries the `root\\WebAdministration` WMI namespace to check for running IIS workers. If it successfully retrieves a list from this namespace, it will append the name of the worker's application pool to the corresponding process. include/exclude matching occurs before this name is appended, so you don't have to take this name in consideration when writing your expression.
Note that this specific feature **only works** if the [IIS Management Scripts and Tools](https://learn.microsoft.com/en-us/iis/manage/scripting/managing-sites-with-the-iis-wmi-provider) are installed. If they are not installed then all worker processes return as just `w3wp`. Note that this specific feature **only works** if the [IIS Management Scripts and Tools](https://learn.microsoft.com/en-us/iis/manage/scripting/managing-sites-with-the-iis-wmi-provider) are installed. If they are not installed then all worker processes return as just `w3wp`.

View File

@@ -10,17 +10,17 @@ Enabled by default? | No
## Flags ## Flags
### `--collector.scheduled_task.whitelist` ### `--collector.scheduled_task.include`
If given, the path of the task needs to match the whitelist regexp in order for the corresponding metrics to be reported. If given, the path of the task needs to match the include regexp in order for the corresponding metrics to be reported.
E.G. `--collector.scheduled_task.whitelist="Firefox.*"` E.G. `--collector.scheduled_task.include="Firefox.*"`
### `--collector.scheduled_task.blacklist` ### `--collector.scheduled_task.exclude`
If given, the path of the task needs to *not* match the blacklist regexp in order for the corresponding metrics to be reported. If given, the path of the task needs to *not* match the exclude regexp in order for the corresponding metrics to be reported.
E.G. `--collector.scheduled_task.blacklist="/Microsoft/.+"` E.G. `--collector.scheduled_task.exclude="/Microsoft/.+"`
## Metrics ## Metrics

View File

@@ -12,13 +12,13 @@ Enabled by default? | No
## Flags ## Flags
### `--collector.smtp.server-whitelist` ### `--collector.smtp.server-include`
If given, a virtual SMTP server needs to match the whitelist regexp in order for the corresponding metrics to be reported. If given, a virtual SMTP server needs to match the include regexp in order for the corresponding metrics to be reported.
### `--collector.smtp.server-blacklist` ### `--collector.smtp.server-exclude`
If given, a virtual SMTP server needs to *not* match the blacklist regexp in order for the corresponding metrics to be reported. If given, a virtual SMTP server needs to *not* match the exclude regexp in order for the corresponding metrics to be reported.
## Metrics ## Metrics

View File

@@ -6,7 +6,7 @@ collector:
service: service:
services-where: Name='windows_exporter' services-where: Name='windows_exporter'
scheduled_task: scheduled_task:
blacklist: /Microsoft/.+ include: /Microsoft/.+
log: log:
level: debug level: debug
scrape: scrape: