Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions collector/diskstats_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
package collector

import (
"errors"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"gopkg.in/alecthomas/kingpin.v2"
)

const (
Expand All @@ -28,6 +33,10 @@ const (
var (
diskLabelNames = []string{"device"}

diskstatsDeviceExclude = kingpin.Flag("collector.diskstats.device-exclude", "Regexp of diskstats devices to exclude (mutually exclusive to device-include).").Default(diskstatsDefaultIgnoredDevices).String()
oldDiskstatsDeviceExclude = kingpin.Flag("collector.diskstats.ignored-devices", "DEPRECATED: Use collector.diskstats.device-exclude").String()
diskstatsDeviceInclude = kingpin.Flag("collector.diskstats.device-include", "Regexp of diskstats devices to include (mutually exclusive to device-exclude).").String()

readsCompletedDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, diskSubsystem, "reads_completed_total"),
"The total number of reads completed successfully.",
Expand Down Expand Up @@ -72,3 +81,28 @@ var (
nil,
)
)

func newDiskstatsDeviceFilter(logger log.Logger) (deviceFilter, error) {
if *oldDiskstatsDeviceExclude != "" {
if *diskstatsDeviceExclude == "" {
level.Warn(logger).Log("msg", "--collector.diskstats.ignored-devices is DEPRECATED and will be removed in 2.0.0, use --collector.diskstats.device-exclude")
*diskstatsDeviceExclude = *oldDiskstatsDeviceExclude
} else {
return deviceFilter{}, errors.New("--collector.diskstats.ignored-devices and --collector.diskstats.device-exclude are mutually exclusive")
}
}

if *diskstatsDeviceExclude != "" && *diskstatsDeviceInclude != "" {
return deviceFilter{}, errors.New("device-exclude & device-include are mutually exclusive")
}

if *diskstatsDeviceExclude != "" {
level.Info(logger).Log("msg", "Parsed flag --collector.diskstats.device-exclude", "flag", *diskstatsDeviceExclude)
}

if *diskstatsDeviceInclude != "" {
level.Info(logger).Log("msg", "Parsed Flag --collector.diskstats.device-include", "flag", *diskstatsDeviceInclude)
}

return newDeviceFilter(*diskstatsDeviceExclude, *diskstatsDeviceInclude), nil
}
20 changes: 17 additions & 3 deletions collector/diskstats_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ import (
"github.com/prometheus/client_golang/prometheus"
)

const diskstatsDefaultIgnoredDevices = ""

type typedDescFunc struct {
typedDesc
value func(stat *iostat.DriveStats) float64
}

type diskstatsCollector struct {
descs []typedDescFunc
logger log.Logger
descs []typedDescFunc

deviceFilter deviceFilter
logger log.Logger
}

func init() {
Expand All @@ -42,6 +46,11 @@ func init() {
func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
var diskLabelNames = []string{"device"}

deviceFilter, err := newDiskstatsDeviceFilter(logger)
if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
}

return &diskstatsCollector{
descs: []typedDescFunc{
{
Expand Down Expand Up @@ -183,7 +192,9 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
},
},
},
logger: logger,

deviceFilter: deviceFilter,
logger: logger,
}, nil
}

Expand All @@ -194,6 +205,9 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
}

for _, stats := range diskStats {
if c.deviceFilter.ignored(stats.Name) {
continue
}
for _, desc := range c.descs {
v := desc.value(stats)
ch <- desc.mustNewConstMetric(v, stats.Name)
Expand Down
31 changes: 14 additions & 17 deletions collector/diskstats_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ package collector

import (
"fmt"
"regexp"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/procfs/blockdevice"
"gopkg.in/alecthomas/kingpin.v2"
)

const (
Expand All @@ -33,10 +29,8 @@ const (
// Read sectors and write sectors are the "standard UNIX 512-byte sectors, not any device- or filesystem-specific block size."
// See also https://www.kernel.org/doc/Documentation/block/stat.txt
unixSectorSize = 512.0
)

var (
ignoredDevices = kingpin.Flag("collector.diskstats.ignored-devices", "Regexp of devices to ignore for diskstats.").Default("^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$").String()
diskstatsDefaultIgnoredDevices = "^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"
)

type typedFactorDesc struct {
Expand All @@ -49,11 +43,11 @@ func (d *typedFactorDesc) mustNewConstMetric(value float64, labels ...string) pr
}

type diskstatsCollector struct {
ignoredDevicesPattern *regexp.Regexp
fs blockdevice.FS
infoDesc typedFactorDesc
descs []typedFactorDesc
logger log.Logger
deviceFilter deviceFilter
fs blockdevice.FS
infoDesc typedFactorDesc
descs []typedFactorDesc
logger log.Logger
}

func init() {
Expand All @@ -69,9 +63,14 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}

deviceFilter, err := newDiskstatsDeviceFilter(logger)
if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
}

return &diskstatsCollector{
ignoredDevicesPattern: regexp.MustCompile(*ignoredDevices),
fs: fs,
deviceFilter: deviceFilter,
fs: fs,
infoDesc: typedFactorDesc{
desc: prometheus.NewDesc(prometheus.BuildFQName(namespace, diskSubsystem, "info"),
"Info of /sys/block/<block_device>.",
Expand Down Expand Up @@ -194,11 +193,9 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {

for _, stats := range diskStats {
dev := stats.DeviceName
if c.ignoredDevicesPattern.MatchString(dev) {
level.Debug(c.logger).Log("msg", "Ignoring device", "device", dev, "pattern", c.ignoredDevicesPattern)
if c.deviceFilter.ignored(dev) {
continue
}

ch <- c.infoDesc.mustNewConstMetric(1.0, dev, fmt.Sprint(stats.MajorNumber), fmt.Sprint(stats.MinorNumber))

statCount := stats.IoStatsCount - 3 // Total diskstats record count, less MajorNumber, MinorNumber and DeviceName
Expand Down
2 changes: 1 addition & 1 deletion collector/diskstats_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func NewTestDiskStatsCollector(logger log.Logger) (prometheus.Collector, error)
func TestDiskStats(t *testing.T) {
*sysPath = "fixtures/sys"
*procPath = "fixtures/proc"
*ignoredDevices = "^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"
*diskstatsDeviceExclude = "^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"
testcase := `# HELP node_disk_discard_time_seconds_total This is the total number of seconds spent by all discards.
# TYPE node_disk_discard_time_seconds_total counter
node_disk_discard_time_seconds_total{device="sdb"} 11.13
Expand Down
19 changes: 17 additions & 2 deletions collector/diskstats_openbsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package collector

import (
"fmt"
"unsafe"

"github.com/go-kit/log"
Expand All @@ -30,13 +31,17 @@ import (
*/
import "C"

const diskstatsDefaultIgnoredDevices = ""

type diskstatsCollector struct {
rxfer typedDesc
rbytes typedDesc
wxfer typedDesc
wbytes typedDesc
time typedDesc
logger log.Logger

deviceFilter deviceFilter
logger log.Logger
}

func init() {
Expand All @@ -45,13 +50,20 @@ func init() {

// NewDiskstatsCollector returns a new Collector exposing disk device stats.
func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
deviceFilter, err := newDiskstatsDeviceFilter(logger)
if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
}

return &diskstatsCollector{
rxfer: typedDesc{readsCompletedDesc, prometheus.CounterValue},
rbytes: typedDesc{readBytesDesc, prometheus.CounterValue},
wxfer: typedDesc{writesCompletedDesc, prometheus.CounterValue},
wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue},
time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue},
logger: logger,

deviceFilter: deviceFilter,
logger: logger,
}, nil
}

Expand All @@ -66,6 +78,9 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {

for i := 0; i < ndisks; i++ {
diskname := C.GoString(&diskstats[i].ds_name[0])
if c.deviceFilter.ignored(diskname) {
continue
}

ch <- c.rxfer.mustNewConstMetric(float64(diskstats[i].ds_rxfer), diskname)
ch <- c.rbytes.mustNewConstMetric(float64(diskstats[i].ds_rbytes), diskname)
Expand Down
19 changes: 17 additions & 2 deletions collector/diskstats_openbsd_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package collector

import (
"fmt"
"unsafe"

"github.com/go-kit/log"
Expand All @@ -26,6 +27,8 @@ import (

const (
DS_DISKNAMELEN = 16

diskstatsDefaultIgnoredDevices = ""
)

type DiskStats struct {
Expand All @@ -47,7 +50,9 @@ type diskstatsCollector struct {
wxfer typedDesc
wbytes typedDesc
time typedDesc
logger log.Logger

deviceFilter deviceFilter
logger log.Logger
}

func init() {
Expand All @@ -56,13 +61,20 @@ func init() {

// NewDiskstatsCollector returns a new Collector exposing disk device stats.
func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
deviceFilter, err := newDiskstatsDeviceFilter(logger)
if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
}

return &diskstatsCollector{
rxfer: typedDesc{readsCompletedDesc, prometheus.CounterValue},
rbytes: typedDesc{readBytesDesc, prometheus.CounterValue},
wxfer: typedDesc{writesCompletedDesc, prometheus.CounterValue},
wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue},
time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue},
logger: logger,

deviceFilter: deviceFilter,
logger: logger,
}, nil
}

Expand All @@ -78,6 +90,9 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {
for i := 0; i < ndisks; i++ {
dn := *(*[DS_DISKNAMELEN]int8)(unsafe.Pointer(&diskstats[i].Name[0]))
diskname := int8ToString(dn[:])
if c.deviceFilter.ignored(diskname) {
continue
}

ch <- c.rxfer.mustNewConstMetric(float64(diskstats[i].Rxfer), diskname)
ch <- c.rbytes.mustNewConstMetric(float64(diskstats[i].Rbytes), diskname)
Expand Down