utils: share the include/exclude regexp flag handling (#2737)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-16 00:07:30 +02:00
committed by GitHub
parent 34738679a1
commit 81ce8ef79d
18 changed files with 422 additions and 224 deletions
+8 -26
View File
@@ -23,7 +23,6 @@ import (
"fmt"
"log/slog"
"regexp"
"slices"
"strconv"
"sync"
"time"
@@ -32,6 +31,7 @@ import (
"github.com/prometheus-community/windows_exporter/internal/labelcache"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/windows"
)
@@ -129,17 +129,17 @@ func NewWithFlags(app *kingpin.Application) *Collector {
config: ConfigDefaults,
}
var processExclude, processInclude string
app.Flag(
utils.RegexpFlag(app,
"collector.process.exclude",
"Regexp of processes to exclude. Process name must both match include and not match exclude to be included.",
).Default("").StringVar(&processExclude)
"", &c.config.ProcessExclude,
)
app.Flag(
utils.RegexpFlag(app,
"collector.process.include",
"Regexp of processes to include. Process name must both match include and not match exclude to be included.",
).Default(".+").StringVar(&processInclude)
".+", &c.config.ProcessInclude,
)
app.Flag(
"collector.process.iis",
@@ -151,22 +151,6 @@ func NewWithFlags(app *kingpin.Application) *Collector {
"If enabled, the full cmdline is exposed to the windows_process_info metrics.",
).Default(strconv.FormatBool(c.config.EnableCMDLine)).BoolVar(&c.config.EnableCMDLine)
app.Action(func(*kingpin.ParseContext) error {
var err error
c.config.ProcessExclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", processExclude))
if err != nil {
return fmt.Errorf("collector.process.exclude: %w", err)
}
c.config.ProcessInclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", processInclude))
if err != nil {
return fmt.Errorf("collector.process.include: %w", err)
}
return nil
})
return c
}
@@ -195,9 +179,7 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
c.infoCache = nil
c.lookupCache = sync.Map{}
// The flags wrap the expressions in ^(?:...)$, the defaults of [New] are [types.RegExpAny] and [types.RegExpEmpty].
if slices.Contains([]string{"^(?:.+)$", "^(?:.*)$", types.RegExpAny.String()}, c.config.ProcessInclude.String()) &&
slices.Contains([]string{"^(?:)$", types.RegExpEmpty.String()}, c.config.ProcessExclude.String()) {
if utils.IsMatchAll(c.config.ProcessInclude) && utils.IsMatchNone(c.config.ProcessExclude) {
logger.Warn("No filters specified for process collector. This will generate a very large number of metrics!")
}
@@ -22,10 +22,32 @@ import (
"os/user"
"testing"
"github.com/alecthomas/kingpin/v2"
"github.com/stretchr/testify/require"
"golang.org/x/sys/windows"
)
// The flags store anchored expressions in the configuration of the collector.
func TestNewWithFlagsFilters(t *testing.T) {
t.Parallel()
app := kingpin.New("test", "test")
c := NewWithFlags(app)
_, err := app.Parse([]string{"--collector.process.include=foo|bar"})
require.NoError(t, err)
require.Equal(t, "^(?:foo|bar)$", c.config.ProcessInclude.String())
require.Equal(t, "^(?:)$", c.config.ProcessExclude.String())
require.True(t, c.config.ProcessInclude.MatchString("bar"))
require.False(t, c.config.ProcessInclude.MatchString("foobar"))
app = kingpin.New("test", "test")
NewWithFlags(app)
_, err = app.Parse([]string{"--collector.process.exclude=("})
require.ErrorContains(t, err, "collector.process.exclude: error parsing regexp")
}
// The owner label must use the Windows DOMAIN\user form, as os/user reports it.
func TestGetProcessOwner(t *testing.T) {
t.Parallel()
+1 -7
View File
@@ -23,19 +23,13 @@ import (
"strconv"
"testing"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/collector/process"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
"github.com/stretchr/testify/require"
)
func BenchmarkProcessCollector(b *testing.B) {
// PrinterInclude is not set in testing context (kingpin flags not parsed), causing the collector to skip all processes.
localProcessInclude := ".+"
// No context name required as collector source is WMI
testutils.FuncBenchmarkCollector(b, process.Name, process.NewWithFlags, func(app *kingpin.Application) {
app.GetFlag("collector.process.include").StringVar(&localProcessInclude)
})
testutils.FuncBenchmarkCollector(b, process.Name, process.NewWithFlags)
}
func TestCollector(t *testing.T) {