From e44ce4c56df98e519cd5ee546de72a22679679e1 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Tue, 5 Nov 2024 10:36:13 +0100 Subject: [PATCH] Add filesystem include flags Add support for allow lists of filesystem mount points and filesystem types. This allows for less messy regexps when you want to target only specific lists of mount points or filesystem types. Signed-off-by: Ben Kochie --- README.md | 4 +- collector/filesystem_aix.go | 4 +- collector/filesystem_bsd.go | 4 +- collector/filesystem_common.go | 132 ++++++++++++++++++++++---------- collector/filesystem_freebsd.go | 4 +- collector/filesystem_linux.go | 6 +- collector/filesystem_netbsd.go | 4 +- collector/filesystem_openbsd.go | 4 +- 8 files changed, 108 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 44a9d2b1fe..ff5d27ead0 100644 --- a/README.md +++ b/README.md @@ -99,8 +99,8 @@ cpu | flags | --collector.cpu.info.flags-include | N/A diskstats | device | --collector.diskstats.device-include | --collector.diskstats.device-exclude ethtool | device | --collector.ethtool.device-include | --collector.ethtool.device-exclude ethtool | metrics | --collector.ethtool.metrics-include | N/A -filesystem | fs-types | N/A | --collector.filesystem.fs-types-exclude -filesystem | mount-points | N/A | --collector.filesystem.mount-points-exclude +filesystem | fs-types | --collector.filesystem.fs-types-include | --collector.filesystem.fs-types-exclude +filesystem | mount-points | --collector.filesystem.mount-points-include | --collector.filesystem.mount-points-exclude hwmon | chip | --collector.hwmon.chip-include | --collector.hwmon.chip-exclude hwmon | sensor | --collector.hwmon.sensor-include | --collector.hwmon.sensor-exclude interrupts | name | --collector.interrupts.name-include | --collector.interrupts.name-exclude diff --git a/collector/filesystem_aix.go b/collector/filesystem_aix.go index 863a26a000..a1314a0f01 100644 --- a/collector/filesystem_aix.go +++ b/collector/filesystem_aix.go @@ -32,12 +32,12 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { return nil, err } for _, stat := range fsStat { - if c.excludedMountPointsPattern.MatchString(stat.MountPoint) { + if c.mountPointFilter.ignored(stat.MountPoint) { c.logger.Debug("Ignoring mount point", "mountpoint", stat.MountPoint) continue } fstype := stat.TypeString() - if c.excludedFSTypesPattern.MatchString(fstype) { + if c.fsTypeFilter.ignored(fstype) { c.logger.Debug("Ignoring fs type", "type", fstype) continue } diff --git a/collector/filesystem_bsd.go b/collector/filesystem_bsd.go index 2db3fb8ff3..d586c9ca90 100644 --- a/collector/filesystem_bsd.go +++ b/collector/filesystem_bsd.go @@ -48,14 +48,14 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { stats = []filesystemStats{} for i := 0; i < int(count); i++ { mountpoint := C.GoString(&mnt[i].f_mntonname[0]) - if c.excludedMountPointsPattern.MatchString(mountpoint) { + if c.mountPointFilter.ignored(mountpoint) { c.logger.Debug("Ignoring mount point", "mountpoint", mountpoint) continue } device := C.GoString(&mnt[i].f_mntfromname[0]) fstype := C.GoString(&mnt[i].f_fstypename[0]) - if c.excludedFSTypesPattern.MatchString(fstype) { + if c.fsTypeFilter.ignored(fstype) { c.logger.Debug("Ignoring fs type", "type", fstype) continue } diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go index 0ec55e8af6..41d439c80e 100644 --- a/collector/filesystem_common.go +++ b/collector/filesystem_common.go @@ -19,8 +19,8 @@ package collector import ( "errors" + "fmt" "log/slog" - "regexp" "github.com/alecthomas/kingpin/v2" "github.com/prometheus/client_golang/prometheus" @@ -36,7 +36,7 @@ var ( mountPointsExcludeSet bool mountPointsExclude = kingpin.Flag( "collector.filesystem.mount-points-exclude", - "Regexp of mount points to exclude for filesystem collector.", + "Regexp of mount points to exclude for filesystem collector. (mutually exclusive to mount-points-include)", ).Default(defMountPointsExcluded).PreAction(func(c *kingpin.ParseContext) error { mountPointsExcludeSet = true return nil @@ -45,11 +45,15 @@ var ( "collector.filesystem.ignored-mount-points", "Regexp of mount points to ignore for filesystem collector.", ).Hidden().String() + mountPointsInclude = kingpin.Flag( + "collector.filesystem.mount-points-include", + "Regexp of mount points to include for filesystem collector. (mutually exclusive to mount-points-exclude)", + ).String() fsTypesExcludeSet bool fsTypesExclude = kingpin.Flag( "collector.filesystem.fs-types-exclude", - "Regexp of filesystem types to exclude for filesystem collector.", + "Regexp of filesystem types to exclude for filesystem collector. (mutually exclusive to fs-types-include)", ).Default(defFSTypesExcluded).PreAction(func(c *kingpin.ParseContext) error { fsTypesExcludeSet = true return nil @@ -58,13 +62,17 @@ var ( "collector.filesystem.ignored-fs-types", "Regexp of filesystem types to ignore for filesystem collector.", ).Hidden().String() + fsTypesInclude = kingpin.Flag( + "collector.filesystem.fs-types-include", + "Regexp of filesystem types to exclude for filesystem collector. (mutually exclusive to fs-types-exclude)", + ).String() filesystemLabelNames = []string{"device", "mountpoint", "fstype", "device_error"} ) type filesystemCollector struct { - excludedMountPointsPattern *regexp.Regexp - excludedFSTypesPattern *regexp.Regexp + mountPointFilter deviceFilter + fsTypeFilter deviceFilter sizeDesc, freeDesc, availDesc *prometheus.Desc filesDesc, filesFreeDesc *prometheus.Desc roDesc, deviceErrorDesc *prometheus.Desc @@ -89,29 +97,7 @@ func init() { // NewFilesystemCollector returns a new Collector exposing filesystems stats. func NewFilesystemCollector(logger *slog.Logger) (Collector, error) { - if *oldMountPointsExcluded != "" { - if !mountPointsExcludeSet { - logger.Warn("--collector.filesystem.ignored-mount-points is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.mount-points-exclude") - *mountPointsExclude = *oldMountPointsExcluded - } else { - return nil, errors.New("--collector.filesystem.ignored-mount-points and --collector.filesystem.mount-points-exclude are mutually exclusive") - } - } - - if *oldFSTypesExcluded != "" { - if !fsTypesExcludeSet { - logger.Warn("--collector.filesystem.ignored-fs-types is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.fs-types-exclude") - *fsTypesExclude = *oldFSTypesExcluded - } else { - return nil, errors.New("--collector.filesystem.ignored-fs-types and --collector.filesystem.fs-types-exclude are mutually exclusive") - } - } - - subsystem := "filesystem" - logger.Info("Parsed flag --collector.filesystem.mount-points-exclude", "flag", *mountPointsExclude) - mountPointPattern := regexp.MustCompile(*mountPointsExclude) - logger.Info("Parsed flag --collector.filesystem.fs-types-exclude", "flag", *fsTypesExclude) - filesystemsTypesPattern := regexp.MustCompile(*fsTypesExclude) + const subsystem = "filesystem" sizeDesc := prometheus.NewDesc( prometheus.BuildFQName(namespace, subsystem, "size_bytes"), @@ -162,18 +148,28 @@ func NewFilesystemCollector(logger *slog.Logger) (Collector, error) { nil, ) + mountPointFilter, err := newMountPointsFilter(logger) + if err != nil { + return nil, fmt.Errorf("unable to parse mount points filter flags: %w", err) + } + + fsTypeFilter, err := newFSTypeFilter(logger) + if err != nil { + return nil, fmt.Errorf("unable to parse fs types filter flags: %w", err) + } + return &filesystemCollector{ - excludedMountPointsPattern: mountPointPattern, - excludedFSTypesPattern: filesystemsTypesPattern, - sizeDesc: sizeDesc, - freeDesc: freeDesc, - availDesc: availDesc, - filesDesc: filesDesc, - filesFreeDesc: filesFreeDesc, - roDesc: roDesc, - deviceErrorDesc: deviceErrorDesc, - mountInfoDesc: mountInfoDesc, - logger: logger, + mountPointFilter: mountPointFilter, + fsTypeFilter: fsTypeFilter, + sizeDesc: sizeDesc, + freeDesc: freeDesc, + availDesc: availDesc, + filesDesc: filesDesc, + filesFreeDesc: filesFreeDesc, + roDesc: roDesc, + deviceErrorDesc: deviceErrorDesc, + mountInfoDesc: mountInfoDesc, + logger: logger, }, nil } @@ -230,3 +226,61 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error { } return nil } + +func newMountPointsFilter(logger *slog.Logger) (deviceFilter, error) { + if *oldMountPointsExcluded != "" { + if !mountPointsExcludeSet { + logger.Warn("--collector.filesystem.ignored-mount-points is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.mount-points-exclude") + *mountPointsExclude = *oldMountPointsExcluded + } else { + return deviceFilter{}, errors.New("--collector.filesystem.ignored-mount-points and --collector.filesystem.mount-points-exclude are mutually exclusive") + } + } + + if *mountPointsInclude != "" && !mountPointsExcludeSet { + logger.Debug("mount-points-exclude flag not set when mount-points-include flag is set, assuming include is desired") + *mountPointsExclude = "" + } + + if *mountPointsExclude != "" && *mountPointsInclude != "" { + return deviceFilter{}, errors.New("--collector.filesystem.mount-points-exclude and --collector.filesystem.mount-points-include are mutually exclusive") + } + + if *mountPointsExclude != "" { + logger.Info("Parsed flag --collector.filesystem.mount-points-exclude", "flag", *mountPointsExclude) + } + if *mountPointsInclude != "" { + logger.Info("Parsed flag --collector.filesystem.mount-points-include", "flag", *mountPointsInclude) + } + + return newDeviceFilter(*mountPointsExclude, *mountPointsInclude), nil +} + +func newFSTypeFilter(logger *slog.Logger) (deviceFilter, error) { + if *oldFSTypesExcluded != "" { + if !fsTypesExcludeSet { + logger.Warn("--collector.filesystem.ignored-fs-types is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.fs-types-exclude") + *fsTypesExclude = *oldFSTypesExcluded + } else { + return deviceFilter{}, errors.New("--collector.filesystem.ignored-fs-types and --collector.filesystem.fs-types-exclude are mutually exclusive") + } + } + + if *fsTypesInclude != "" && !fsTypesExcludeSet { + logger.Debug("fs-types-exclude flag not set when fs-types-include flag is set, assuming include is desired") + *fsTypesExclude = "" + } + + if *fsTypesExclude != "" && *fsTypesInclude != "" { + return deviceFilter{}, errors.New("--collector.filesystem.fs-types-exclude and --collector.filesystem.fs-types-include are mutually exclusive") + } + + if *fsTypesExclude != "" { + logger.Info("Parsed flag --collector.filesystem.fs-types-exclude", "flag", *fsTypesExclude) + } + if *fsTypesInclude != "" { + logger.Info("Parsed flag --collector.filesystem.fs-types-include", "flag", *fsTypesInclude) + } + + return newDeviceFilter(*fsTypesExclude, *fsTypesInclude), nil +} diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go index 2a6026d3a2..502ae0a850 100644 --- a/collector/filesystem_freebsd.go +++ b/collector/filesystem_freebsd.go @@ -39,14 +39,14 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { stats := []filesystemStats{} for _, fs := range buf { mountpoint := unix.ByteSliceToString(fs.Mntonname[:]) - if c.excludedMountPointsPattern.MatchString(mountpoint) { + if c.mountPointFilter.ignored(mountpoint) { c.logger.Debug("Ignoring mount point", "mountpoint", mountpoint) continue } device := unix.ByteSliceToString(fs.Mntfromname[:]) fstype := unix.ByteSliceToString(fs.Fstypename[:]) - if c.excludedFSTypesPattern.MatchString(fstype) { + if c.fsTypeFilter.ignored(fstype) { c.logger.Debug("Ignoring fs type", "type", fstype) continue } diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index 19c3971760..3a7bda4d24 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -73,12 +73,12 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { go func() { for _, labels := range mps { - if c.excludedMountPointsPattern.MatchString(labels.mountPoint) { + if c.mountPointFilter.ignored(labels.mountPoint) { c.logger.Debug("Ignoring mount point", "mountpoint", labels.mountPoint) continue } - if c.excludedFSTypesPattern.MatchString(labels.fsType) { - c.logger.Debug("Ignoring fs", "type", labels.fsType) + if c.fsTypeFilter.ignored(labels.fsType) { + c.logger.Debug("Ignoring fs type", "type", labels.fsType) continue } diff --git a/collector/filesystem_netbsd.go b/collector/filesystem_netbsd.go index ba6a9f55a5..c7395893a7 100644 --- a/collector/filesystem_netbsd.go +++ b/collector/filesystem_netbsd.go @@ -97,14 +97,14 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { stats = []filesystemStats{} for _, v := range mnt { mountpoint := unix.ByteSliceToString(v.F_mntonname[:]) - if c.excludedMountPointsPattern.MatchString(mountpoint) { + if c.mountPointFilter.ignored(mountpoint) { c.logger.Debug("msg", "Ignoring mount point", "mountpoint", mountpoint) continue } device := unix.ByteSliceToString(v.F_mntfromname[:]) fstype := unix.ByteSliceToString(v.F_fstypename[:]) - if c.excludedFSTypesPattern.MatchString(fstype) { + if c.fsTypeFilter.ignored(fstype) { c.logger.Debug("msg", "Ignoring fs type", "type", fstype) continue } diff --git a/collector/filesystem_openbsd.go b/collector/filesystem_openbsd.go index d7489364f9..fa9f8eb871 100644 --- a/collector/filesystem_openbsd.go +++ b/collector/filesystem_openbsd.go @@ -41,14 +41,14 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { stats = []filesystemStats{} for _, v := range mnt { mountpoint := unix.ByteSliceToString(v.F_mntonname[:]) - if c.excludedMountPointsPattern.MatchString(mountpoint) { + if c.mountPointFilter.ignored(mountpoint) { c.logger.Debug("Ignoring mount point", "mountpoint", mountpoint) continue } device := unix.ByteSliceToString(v.F_mntfromname[:]) fstype := unix.ByteSliceToString(v.F_fstypename[:]) - if c.excludedFSTypesPattern.MatchString(fstype) { + if c.fsTypeFilter.ignored(fstype) { c.logger.Debug("Ignoring fs type", "type", fstype) continue }