prometheusmetricshost-metricsmachine-metricsnode-metricsprocfsprometheus-exportersystem-informationsystem-metrics
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
7.7 KiB
232 lines
7.7 KiB
// Copyright 2015 The Prometheus Authors |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
|
|
//go:build !nofilesystem && (linux || freebsd || netbsd || openbsd || darwin || dragonfly || aix) |
|
// +build !nofilesystem |
|
// +build linux freebsd netbsd openbsd darwin dragonfly aix |
|
|
|
package collector |
|
|
|
import ( |
|
"errors" |
|
"log/slog" |
|
"regexp" |
|
|
|
"github.com/alecthomas/kingpin/v2" |
|
"github.com/prometheus/client_golang/prometheus" |
|
) |
|
|
|
// Arch-dependent implementation must define: |
|
// * defMountPointsExcluded |
|
// * defFSTypesExcluded |
|
// * filesystemLabelNames |
|
// * filesystemCollector.GetStats |
|
|
|
var ( |
|
mountPointsExcludeSet bool |
|
mountPointsExclude = kingpin.Flag( |
|
"collector.filesystem.mount-points-exclude", |
|
"Regexp of mount points to exclude for filesystem collector.", |
|
).Default(defMountPointsExcluded).PreAction(func(c *kingpin.ParseContext) error { |
|
mountPointsExcludeSet = true |
|
return nil |
|
}).String() |
|
oldMountPointsExcluded = kingpin.Flag( |
|
"collector.filesystem.ignored-mount-points", |
|
"Regexp of mount points to ignore for filesystem collector.", |
|
).Hidden().String() |
|
|
|
fsTypesExcludeSet bool |
|
fsTypesExclude = kingpin.Flag( |
|
"collector.filesystem.fs-types-exclude", |
|
"Regexp of filesystem types to exclude for filesystem collector.", |
|
).Default(defFSTypesExcluded).PreAction(func(c *kingpin.ParseContext) error { |
|
fsTypesExcludeSet = true |
|
return nil |
|
}).String() |
|
oldFSTypesExcluded = kingpin.Flag( |
|
"collector.filesystem.ignored-fs-types", |
|
"Regexp of filesystem types to ignore for filesystem collector.", |
|
).Hidden().String() |
|
|
|
filesystemLabelNames = []string{"device", "mountpoint", "fstype", "device_error"} |
|
) |
|
|
|
type filesystemCollector struct { |
|
excludedMountPointsPattern *regexp.Regexp |
|
excludedFSTypesPattern *regexp.Regexp |
|
sizeDesc, freeDesc, availDesc *prometheus.Desc |
|
filesDesc, filesFreeDesc *prometheus.Desc |
|
roDesc, deviceErrorDesc *prometheus.Desc |
|
mountInfoDesc *prometheus.Desc |
|
logger *slog.Logger |
|
} |
|
|
|
type filesystemLabels struct { |
|
device, mountPoint, fsType, options, deviceError, major, minor string |
|
} |
|
|
|
type filesystemStats struct { |
|
labels filesystemLabels |
|
size, free, avail float64 |
|
files, filesFree float64 |
|
ro, deviceError float64 |
|
} |
|
|
|
func init() { |
|
registerCollector("filesystem", defaultEnabled, NewFilesystemCollector) |
|
} |
|
|
|
// 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) |
|
|
|
sizeDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "size_bytes"), |
|
"Filesystem size in bytes.", |
|
filesystemLabelNames, nil, |
|
) |
|
|
|
freeDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "free_bytes"), |
|
"Filesystem free space in bytes.", |
|
filesystemLabelNames, nil, |
|
) |
|
|
|
availDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "avail_bytes"), |
|
"Filesystem space available to non-root users in bytes.", |
|
filesystemLabelNames, nil, |
|
) |
|
|
|
filesDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "files"), |
|
"Filesystem total file nodes.", |
|
filesystemLabelNames, nil, |
|
) |
|
|
|
filesFreeDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "files_free"), |
|
"Filesystem total free file nodes.", |
|
filesystemLabelNames, nil, |
|
) |
|
|
|
roDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "readonly"), |
|
"Filesystem read-only status.", |
|
filesystemLabelNames, nil, |
|
) |
|
|
|
deviceErrorDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "device_error"), |
|
"Whether an error occurred while getting statistics for the given device.", |
|
filesystemLabelNames, nil, |
|
) |
|
|
|
mountInfoDesc := prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, subsystem, "mount_info"), |
|
"Filesystem mount information.", |
|
[]string{"device", "major", "minor", "mountpoint"}, |
|
nil, |
|
) |
|
|
|
return &filesystemCollector{ |
|
excludedMountPointsPattern: mountPointPattern, |
|
excludedFSTypesPattern: filesystemsTypesPattern, |
|
sizeDesc: sizeDesc, |
|
freeDesc: freeDesc, |
|
availDesc: availDesc, |
|
filesDesc: filesDesc, |
|
filesFreeDesc: filesFreeDesc, |
|
roDesc: roDesc, |
|
deviceErrorDesc: deviceErrorDesc, |
|
mountInfoDesc: mountInfoDesc, |
|
logger: logger, |
|
}, nil |
|
} |
|
|
|
func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error { |
|
stats, err := c.GetStats() |
|
if err != nil { |
|
return err |
|
} |
|
// Make sure we expose a metric once, even if there are multiple mounts |
|
seen := map[filesystemLabels]bool{} |
|
for _, s := range stats { |
|
if seen[s.labels] { |
|
continue |
|
} |
|
seen[s.labels] = true |
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
c.deviceErrorDesc, prometheus.GaugeValue, |
|
s.deviceError, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, |
|
) |
|
ch <- prometheus.MustNewConstMetric( |
|
c.roDesc, prometheus.GaugeValue, |
|
s.ro, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, |
|
) |
|
|
|
if s.deviceError > 0 { |
|
continue |
|
} |
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
c.sizeDesc, prometheus.GaugeValue, |
|
s.size, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, |
|
) |
|
ch <- prometheus.MustNewConstMetric( |
|
c.freeDesc, prometheus.GaugeValue, |
|
s.free, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, |
|
) |
|
ch <- prometheus.MustNewConstMetric( |
|
c.availDesc, prometheus.GaugeValue, |
|
s.avail, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, |
|
) |
|
ch <- prometheus.MustNewConstMetric( |
|
c.filesDesc, prometheus.GaugeValue, |
|
s.files, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, |
|
) |
|
ch <- prometheus.MustNewConstMetric( |
|
c.filesFreeDesc, prometheus.GaugeValue, |
|
s.filesFree, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, |
|
) |
|
ch <- prometheus.MustNewConstMetric( |
|
c.mountInfoDesc, prometheus.GaugeValue, |
|
1.0, s.labels.device, s.labels.major, s.labels.minor, s.labels.mountPoint, |
|
) |
|
} |
|
return nil |
|
}
|
|
|