Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IO stats and ext4 FS stats through new ext4 collector #3047

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
23 changes: 23 additions & 0 deletions collector/diskstats_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ type diskstatsCollector struct {
filesystemInfoDesc typedFactorDesc
deviceMapperInfoDesc typedFactorDesc
ataDescs map[string]typedFactorDesc
ioErrDesc typedFactorDesc
ioDoneDesc typedFactorDesc
logger log.Logger
getUdevDeviceProperties func(uint32, uint32) (udevInfo, error)
}
Expand Down Expand Up @@ -257,6 +259,20 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
), valueType: prometheus.GaugeValue,
},
},
ioErrDesc: typedFactorDesc{
desc: prometheus.NewDesc(prometheus.BuildFQName(namespace, diskSubsystem, "ioerr_total"),
"Number of IO commands that completed with an error.",
[]string{"device"},
nil,
), valueType: prometheus.CounterValue,
},
ioDoneDesc: typedFactorDesc{
desc: prometheus.NewDesc(prometheus.BuildFQName(namespace, diskSubsystem, "iodone_total"),
"Number of completed or rejected IO commands.",
[]string{"device"},
nil,
), valueType: prometheus.CounterValue,
},
logger: logger,
}

Expand Down Expand Up @@ -366,6 +382,13 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
}
}
}

if ioDiskStats, err := c.fs.SysBlockDeviceIOStat(dev); err == nil {
ch <- c.ioDoneDesc.mustNewConstMetric(float64(ioDiskStats.IODoneCount), dev)
ch <- c.ioErrDesc.mustNewConstMetric(float64(ioDiskStats.IOErrCount), dev)
} else {
level.Debug(c.logger).Log("msg", "Error reading IO errors count", "err", err)
}
}
return nil
}
Expand Down
8 changes: 8 additions & 0 deletions collector/diskstats_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ node_disk_io_time_weighted_seconds_total{device="sdb"} 67.07000000000001
node_disk_io_time_weighted_seconds_total{device="sdc"} 17.07
node_disk_io_time_weighted_seconds_total{device="sr0"} 0
node_disk_io_time_weighted_seconds_total{device="vda"} 2.0778722280000001e+06
# HELP node_disk_iodone_total Number of completed or rejected IO commands.
# TYPE node_disk_iodone_total counter
node_disk_iodone_total{device="sda"} 307
node_disk_iodone_total{device="sr0"} 2767
# HELP node_disk_ioerr_total Number of IO commands that completed with an error.
# TYPE node_disk_ioerr_total counter
node_disk_ioerr_total{device="sda"} 3
node_disk_ioerr_total{device="sr0"} 29
# HELP node_disk_read_bytes_total The total number of bytes read successfully.
# TYPE node_disk_read_bytes_total counter
node_disk_read_bytes_total{device="dm-0"} 5.13708655616e+11
Expand Down
110 changes: 110 additions & 0 deletions collector/ext4_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright 2017 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 !noext4
// +build !noext4

package collector

import (
"fmt"

"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/procfs/ext4"
)

// An ext4Collector is a Collector which gathers metrics from ext4 filesystems.
type ext4Collector struct {
fs ext4.FS
logger log.Logger
}

func init() {
registerCollector("ext4", defaultEnabled, NewExt4Collector)
}

// NewExt4Collector returns a new Collector exposing ext4 statistics.
func NewExt4Collector(logger log.Logger) (Collector, error) {
fs, err := ext4.NewFS(*procPath, *sysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}

return &ext4Collector{
fs: fs,
logger: logger,
}, nil
}

// Update implements Collector.
func (c *ext4Collector) Update(ch chan<- prometheus.Metric) error {
stats, err := c.fs.ProcStat()
if err != nil {
return fmt.Errorf("failed to retrieve ext4 stats: %w", err)
}

for _, s := range stats {
c.updateExt4Stats(ch, s)
}

return nil
}

// updateExt4Stats collects statistics for a single ext4 filesystem.
func (c *ext4Collector) updateExt4Stats(ch chan<- prometheus.Metric, s *ext4.Stats) {
const (
subsystem = "ext4"
)
var (
labels = []string{"device"}
)

metrics := []struct {
name string
desc string
value float64
}{
{
name: "errors",
desc: "Number of ext4 filesystem errors.",
value: float64(s.Errors),
},
{
name: "warnings",
desc: "Number of ext4 filesystem warnings.",
value: float64(s.Warnings),
},
{
name: "messages",
desc: "Number of ext4 filesystem log messages.",
value: float64(s.Messages),
},
}

for _, m := range metrics {
desc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, m.name),
m.desc,
labels,
nil,
)

ch <- prometheus.MustNewConstMetric(
desc,
prometheus.CounterValue,
m.value,
s.Name,
)
}
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ require (
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

replace github.com/prometheus/procfs => /home/shb/work/oss/procfs