From 5dc9812da3f8d81ab2eb6498910b5b2e01775753 Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Mon, 10 Jun 2024 16:32:28 +0500 Subject: [PATCH 1/9] Add IO stats and FS stats --- collector/diskstats_linux.go | 57 ++++++++++++++++++++++ collector/diskstats_linux_test.go | 8 ++++ collector/filesystem_common.go | 47 ++++++++++++++++++ collector/filesystem_linux.go | 79 ++++++++++++++++++++++++++++--- 4 files changed, 184 insertions(+), 7 deletions(-) diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index ed5d044a61..e9a86e4aae 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go @@ -22,6 +22,7 @@ import ( "os" "strconv" "strings" + "errors" "github.com/go-kit/log" "github.com/go-kit/log/level" @@ -85,6 +86,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) } @@ -257,6 +260,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, } @@ -366,6 +383,22 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { } } } + + ioCounterFilesPath := fmt.Sprintf("/sys/block/%s/device", dev) + + ioErrFilePath := fmt.Sprintf("%s/ioerr_cnt", ioCounterFilesPath) + if ioErr, err := readHexFileCounter(ioErrFilePath); err == nil { + ch <- c.ioErrDesc.mustNewConstMetric(ioErr, dev) + } else { + level.Debug(c.logger).Log("msg", "Error reading IO errors count", "ioErrFilePath", ioErrFilePath, "err", err) + } + + ioDoneFilePath := fmt.Sprintf("%s/iodone_cnt", ioCounterFilesPath) + if ioDone, err := readHexFileCounter(ioDoneFilePath); err == nil { + ch <- c.ioDoneDesc.mustNewConstMetric(ioDone, dev) + } else { + level.Debug(c.logger).Log("msg", "Error reading IO done count", "ioDoneFilePath", ioDoneFilePath, "err", err) + } } return nil } @@ -405,3 +438,27 @@ func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) { return info, nil } + +func readHexFileCounter(filePath string) (float64, error) { + file, err := os.Open(filePath) + if err != nil { + return 0, err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + if scanner.Scan() { + text := scanner.Text() + // Convert hex string to int64 + errorsCount, err := strconv.ParseInt(text, 0, 64) + if err != nil { + return 0, err + } + return float64(errorsCount), nil + } + + if err := scanner.Err(); err != nil { + return 0, err + } + return 0, errors.New("could not read errors count") +} \ No newline at end of file diff --git a/collector/diskstats_linux_test.go b/collector/diskstats_linux_test.go index 8e969c3e3a..a71a12ef71 100644 --- a/collector/diskstats_linux_test.go +++ b/collector/diskstats_linux_test.go @@ -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 diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go index f5d5135241..6b9ae56f55 100644 --- a/collector/filesystem_common.go +++ b/collector/filesystem_common.go @@ -66,9 +66,12 @@ var ( type filesystemCollector struct { excludedMountPointsPattern *regexp.Regexp excludedFSTypesPattern *regexp.Regexp + excludedFSTypesErrorPattern *regexp.Regexp sizeDesc, freeDesc, availDesc *prometheus.Desc filesDesc, filesFreeDesc *prometheus.Desc roDesc, deviceErrorDesc *prometheus.Desc + errorsDesc, warningsDesc *prometheus.Desc + messagesDesc *prometheus.Desc logger log.Logger } @@ -81,6 +84,8 @@ type filesystemStats struct { size, free, avail float64 files, filesFree float64 ro, deviceError float64 + errors, warnings float64 + messages float64 } func init() { @@ -155,6 +160,24 @@ func NewFilesystemCollector(logger log.Logger) (Collector, error) { filesystemLabelNames, nil, ) + errorsDesc := prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "errors"), + "Number of filesystem errors encountered.", + filesystemLabelNames, nil, + ) + + warningsDesc := prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "warnings"), + "Number of filesystem warnings encountered.", + filesystemLabelNames, nil, + ) + + messagesDesc := prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "messages"), + "Number of filesystem log messages.", + filesystemLabelNames, nil, + ) + return &filesystemCollector{ excludedMountPointsPattern: mountPointPattern, excludedFSTypesPattern: filesystemsTypesPattern, @@ -165,6 +188,9 @@ func NewFilesystemCollector(logger log.Logger) (Collector, error) { filesFreeDesc: filesFreeDesc, roDesc: roDesc, deviceErrorDesc: deviceErrorDesc, + errorsDesc: errorsDesc, + warningsDesc: warningsDesc, + messagesDesc: messagesDesc, logger: logger, }, nil } @@ -215,6 +241,27 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error { c.filesFreeDesc, prometheus.GaugeValue, s.filesFree, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, ) + + if s.errors != -1 { + ch <- prometheus.MustNewConstMetric( + c.errorsDesc, prometheus.CounterValue, + s.errors, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, + ) + } + + if s.warnings != -1 { + ch <- prometheus.MustNewConstMetric( + c.warningsDesc, prometheus.CounterValue, + s.warnings, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, + ) + } + + if s.messages != -1 { + ch <- prometheus.MustNewConstMetric( + c.messagesDesc, prometheus.CounterValue, + s.messages, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, + ) + } } return nil } diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index 1d0c8493b9..3b2d79920d 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -25,6 +25,7 @@ import ( "strings" "sync" "time" + "strconv" "github.com/alecthomas/kingpin/v2" "github.com/go-kit/log" @@ -35,6 +36,7 @@ import ( const ( defMountPointsExcluded = "^/(dev|proc|run/credentials/.+|sys|var/lib/docker/.+|var/lib/containers/storage/.+)($|/)" defFSTypesExcluded = "^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$" + defFSTypesErrorCheck = "^(ext4|scsi)" ) var mountTimeout = kingpin.Flag("collector.filesystem.mount-timeout", @@ -143,14 +145,54 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta } } + errors := float64(-1) + warnings := float64(-1) + messages := float64(-1) + if labels.fsType == "ext4" || labels.fsType == "scsi" { + // For fstype ext4 + // errors_count https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=52c198c6820f68b6fbe1d83f76e34a82bf736024 + // msg_count and warning_count https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1cf006ed19a887c22e085189c8b4a3cbf60d2246 + if labels.fsType == "ext4" { + deviceNameParts := strings.Split(labels.device, "/") + deviceName := deviceNameParts[len(deviceNameParts)-1] + ext4FilesPath := fmt.Sprintf("/sys/fs/ext4/%s", deviceName) + + errorsCountFilePath := fmt.Sprintf("%s/errors_count", ext4FilesPath) + errors, err = readTextFileCounter(errorsCountFilePath) + if err != nil { + level.Debug(c.logger).Log("msg", "Error reading errors count", "errorsCountFilePath", errorsCountFilePath, "err", err) + errors = float64(-1) + } + + warningsCountFilePath := fmt.Sprintf("%s/warning_count", ext4FilesPath) + warnings, err = readTextFileCounter(warningsCountFilePath) + if err != nil { + level.Debug(c.logger).Log("msg", "Error reading warnings count", "warningsCountFilePath", warningsCountFilePath, "err", err) + warnings = float64(-1) + } + + messagesCountFilePath := fmt.Sprintf("%s/msg_count", ext4FilesPath) + messages, err = readTextFileCounter(messagesCountFilePath) + if err != nil { + level.Debug(c.logger).Log("msg", "Error reading errors count", "messagesCountFilePath", messagesCountFilePath, "err", err) + messages = float64(-1) + } + } + } else { + level.Debug(c.logger).Log("msg", "Ignoring unsupported fsType for error checking", "fsType", labels.fsType) + } + return filesystemStats{ - labels: labels, - size: float64(buf.Blocks) * float64(buf.Bsize), - free: float64(buf.Bfree) * float64(buf.Bsize), - avail: float64(buf.Bavail) * float64(buf.Bsize), - files: float64(buf.Files), - filesFree: float64(buf.Ffree), - ro: ro, + labels: labels, + size: float64(buf.Blocks) * float64(buf.Bsize), + free: float64(buf.Bfree) * float64(buf.Bsize), + avail: float64(buf.Bavail) * float64(buf.Bsize), + files: float64(buf.Files), + filesFree: float64(buf.Ffree), + ro: ro, + errors: errors, + warnings: warnings, + messages: messages, } } @@ -219,3 +261,26 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) { return filesystems, scanner.Err() } + +func readTextFileCounter(filePath string) (float64, error) { + file, err := os.Open(filePath) + if err != nil { + return 0, err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + if scanner.Scan() { + text := scanner.Text() + errorsCount, err := strconv.ParseFloat(text, 64) + if err != nil { + return 0, err + } + return errorsCount, nil + } + + if err := scanner.Err(); err != nil { + return 0, err + } + return 0, errors.New("could not read errors count") +} From ae9a356a916c51b86262666a0254fb5b060a4443 Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Mon, 10 Jun 2024 16:40:00 +0500 Subject: [PATCH 2/9] Remove unused const --- collector/filesystem_linux.go | 1 - 1 file changed, 1 deletion(-) diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index 3b2d79920d..12fbb3381b 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -36,7 +36,6 @@ import ( const ( defMountPointsExcluded = "^/(dev|proc|run/credentials/.+|sys|var/lib/docker/.+|var/lib/containers/storage/.+)($|/)" defFSTypesExcluded = "^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$" - defFSTypesErrorCheck = "^(ext4|scsi)" ) var mountTimeout = kingpin.Flag("collector.filesystem.mount-timeout", From 9469e18f10ddd1cfa75ff1c847c7dd433b89b293 Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Mon, 10 Jun 2024 16:41:07 +0500 Subject: [PATCH 3/9] Remove un needed spacking --- collector/filesystem_linux.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index 12fbb3381b..aaa992335a 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -182,16 +182,16 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta } return filesystemStats{ - labels: labels, - size: float64(buf.Blocks) * float64(buf.Bsize), - free: float64(buf.Bfree) * float64(buf.Bsize), - avail: float64(buf.Bavail) * float64(buf.Bsize), - files: float64(buf.Files), - filesFree: float64(buf.Ffree), - ro: ro, - errors: errors, - warnings: warnings, - messages: messages, + labels: labels, + size: float64(buf.Blocks) * float64(buf.Bsize), + free: float64(buf.Bfree) * float64(buf.Bsize), + avail: float64(buf.Bavail) * float64(buf.Bsize), + files: float64(buf.Files), + filesFree: float64(buf.Ffree), + ro: ro, + errors: errors, + warnings: warnings, + messages: messages, } } From 4450e04b7a09543fdeb483f799c0384cdb86eedb Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Tue, 9 Jul 2024 23:08:35 +0500 Subject: [PATCH 4/9] Move file parsing to procfs --- collector/diskstats_linux.go | 19 ++++--------------- go.mod | 2 ++ go.sum | 2 -- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index e9a86e4aae..cda45fe8c0 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go @@ -384,21 +384,10 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { } } - ioCounterFilesPath := fmt.Sprintf("/sys/block/%s/device", dev) - - ioErrFilePath := fmt.Sprintf("%s/ioerr_cnt", ioCounterFilesPath) - if ioErr, err := readHexFileCounter(ioErrFilePath); err == nil { - ch <- c.ioErrDesc.mustNewConstMetric(ioErr, dev) - } else { - level.Debug(c.logger).Log("msg", "Error reading IO errors count", "ioErrFilePath", ioErrFilePath, "err", err) - } - - ioDoneFilePath := fmt.Sprintf("%s/iodone_cnt", ioCounterFilesPath) - if ioDone, err := readHexFileCounter(ioDoneFilePath); err == nil { - ch <- c.ioDoneDesc.mustNewConstMetric(ioDone, dev) - } else { - level.Debug(c.logger).Log("msg", "Error reading IO done count", "ioDoneFilePath", ioDoneFilePath, "err", err) - } + ioDiskStats, err := c.fs.SysBlockDeviceIOStat(dev) + if err != nil { + return fmt.Errorf("couldn't get iodiskstats: %w", err) + } } return nil } diff --git a/go.mod b/go.mod index 0b9e8a0a38..a999034783 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 652f6056e3..0b75b68dfa 100644 --- a/go.sum +++ b/go.sum @@ -82,8 +82,6 @@ github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+a github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= -github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s= -github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= From 9d7fff0b486bebb5953073942e7af558bc7e883b Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Tue, 9 Jul 2024 23:13:48 +0500 Subject: [PATCH 5/9] Remove un needed function --- collector/diskstats_linux.go | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index cda45fe8c0..332055b1f6 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go @@ -384,10 +384,10 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { } } - ioDiskStats, err := c.fs.SysBlockDeviceIOStat(dev) - if err != nil { - return fmt.Errorf("couldn't get iodiskstats: %w", err) - } + // ioDiskStats, err := c.fs.SysBlockDeviceIOStat(dev) + // if err != nil { + // return fmt.Errorf("couldn't get iodiskstats: %w", err) + // } } return nil } @@ -427,27 +427,3 @@ func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) { return info, nil } - -func readHexFileCounter(filePath string) (float64, error) { - file, err := os.Open(filePath) - if err != nil { - return 0, err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - if scanner.Scan() { - text := scanner.Text() - // Convert hex string to int64 - errorsCount, err := strconv.ParseInt(text, 0, 64) - if err != nil { - return 0, err - } - return float64(errorsCount), nil - } - - if err := scanner.Err(); err != nil { - return 0, err - } - return 0, errors.New("could not read errors count") -} \ No newline at end of file From f6706b3bf812670e07fec8df2eef3f668e150b6d Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Thu, 11 Jul 2024 04:19:28 +0500 Subject: [PATCH 6/9] Update disk io stats metrics from procfs --- collector/diskstats_linux.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index 332055b1f6..0fb78ce2f6 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go @@ -22,7 +22,6 @@ import ( "os" "strconv" "strings" - "errors" "github.com/go-kit/log" "github.com/go-kit/log/level" @@ -384,10 +383,12 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { } } - // ioDiskStats, err := c.fs.SysBlockDeviceIOStat(dev) - // if err != nil { - // return fmt.Errorf("couldn't get iodiskstats: %w", err) - // } + 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 } From 229e66ee23f7ff8eca29de1171d4bd077ca6ecab Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Thu, 11 Jul 2024 05:11:49 +0500 Subject: [PATCH 7/9] Revert chnages to filesystem_* packages; add collector for ext4 --- collector/ext4_linux.go | 111 +++++++++++++++++++++++++++++++++ collector/filesystem_common.go | 49 +-------------- collector/filesystem_linux.go | 66 +------------------- 3 files changed, 113 insertions(+), 113 deletions(-) create mode 100644 collector/ext4_linux.go diff --git a/collector/ext4_linux.go b/collector/ext4_linux.go new file mode 100644 index 0000000000..9e86c590cf --- /dev/null +++ b/collector/ext4_linux.go @@ -0,0 +1,111 @@ +// 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, NewXFSCollector) +} + +// NewExt4Collector returns a new Collector exposing ext4 statistics. +func NewExt4Collector(logger log.Logger) (Collector, error) { + fmt.Printf("**************DEBUG SHAHZEB****************") + 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, + ) + } +} \ No newline at end of file diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go index 6b9ae56f55..2c89040614 100644 --- a/collector/filesystem_common.go +++ b/collector/filesystem_common.go @@ -66,12 +66,9 @@ var ( type filesystemCollector struct { excludedMountPointsPattern *regexp.Regexp excludedFSTypesPattern *regexp.Regexp - excludedFSTypesErrorPattern *regexp.Regexp sizeDesc, freeDesc, availDesc *prometheus.Desc filesDesc, filesFreeDesc *prometheus.Desc roDesc, deviceErrorDesc *prometheus.Desc - errorsDesc, warningsDesc *prometheus.Desc - messagesDesc *prometheus.Desc logger log.Logger } @@ -84,8 +81,6 @@ type filesystemStats struct { size, free, avail float64 files, filesFree float64 ro, deviceError float64 - errors, warnings float64 - messages float64 } func init() { @@ -160,24 +155,6 @@ func NewFilesystemCollector(logger log.Logger) (Collector, error) { filesystemLabelNames, nil, ) - errorsDesc := prometheus.NewDesc( - prometheus.BuildFQName(namespace, subsystem, "errors"), - "Number of filesystem errors encountered.", - filesystemLabelNames, nil, - ) - - warningsDesc := prometheus.NewDesc( - prometheus.BuildFQName(namespace, subsystem, "warnings"), - "Number of filesystem warnings encountered.", - filesystemLabelNames, nil, - ) - - messagesDesc := prometheus.NewDesc( - prometheus.BuildFQName(namespace, subsystem, "messages"), - "Number of filesystem log messages.", - filesystemLabelNames, nil, - ) - return &filesystemCollector{ excludedMountPointsPattern: mountPointPattern, excludedFSTypesPattern: filesystemsTypesPattern, @@ -188,9 +165,6 @@ func NewFilesystemCollector(logger log.Logger) (Collector, error) { filesFreeDesc: filesFreeDesc, roDesc: roDesc, deviceErrorDesc: deviceErrorDesc, - errorsDesc: errorsDesc, - warningsDesc: warningsDesc, - messagesDesc: messagesDesc, logger: logger, }, nil } @@ -241,27 +215,6 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error { c.filesFreeDesc, prometheus.GaugeValue, s.filesFree, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, ) - - if s.errors != -1 { - ch <- prometheus.MustNewConstMetric( - c.errorsDesc, prometheus.CounterValue, - s.errors, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, - ) - } - - if s.warnings != -1 { - ch <- prometheus.MustNewConstMetric( - c.warningsDesc, prometheus.CounterValue, - s.warnings, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, - ) - } - - if s.messages != -1 { - ch <- prometheus.MustNewConstMetric( - c.messagesDesc, prometheus.CounterValue, - s.messages, s.labels.device, s.labels.mountPoint, s.labels.fsType, s.labels.deviceError, - ) - } } return nil -} +} \ No newline at end of file diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index aaa992335a..64724b3b17 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -25,7 +25,6 @@ import ( "strings" "sync" "time" - "strconv" "github.com/alecthomas/kingpin/v2" "github.com/go-kit/log" @@ -144,43 +143,6 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta } } - errors := float64(-1) - warnings := float64(-1) - messages := float64(-1) - if labels.fsType == "ext4" || labels.fsType == "scsi" { - // For fstype ext4 - // errors_count https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=52c198c6820f68b6fbe1d83f76e34a82bf736024 - // msg_count and warning_count https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1cf006ed19a887c22e085189c8b4a3cbf60d2246 - if labels.fsType == "ext4" { - deviceNameParts := strings.Split(labels.device, "/") - deviceName := deviceNameParts[len(deviceNameParts)-1] - ext4FilesPath := fmt.Sprintf("/sys/fs/ext4/%s", deviceName) - - errorsCountFilePath := fmt.Sprintf("%s/errors_count", ext4FilesPath) - errors, err = readTextFileCounter(errorsCountFilePath) - if err != nil { - level.Debug(c.logger).Log("msg", "Error reading errors count", "errorsCountFilePath", errorsCountFilePath, "err", err) - errors = float64(-1) - } - - warningsCountFilePath := fmt.Sprintf("%s/warning_count", ext4FilesPath) - warnings, err = readTextFileCounter(warningsCountFilePath) - if err != nil { - level.Debug(c.logger).Log("msg", "Error reading warnings count", "warningsCountFilePath", warningsCountFilePath, "err", err) - warnings = float64(-1) - } - - messagesCountFilePath := fmt.Sprintf("%s/msg_count", ext4FilesPath) - messages, err = readTextFileCounter(messagesCountFilePath) - if err != nil { - level.Debug(c.logger).Log("msg", "Error reading errors count", "messagesCountFilePath", messagesCountFilePath, "err", err) - messages = float64(-1) - } - } - } else { - level.Debug(c.logger).Log("msg", "Ignoring unsupported fsType for error checking", "fsType", labels.fsType) - } - return filesystemStats{ labels: labels, size: float64(buf.Blocks) * float64(buf.Bsize), @@ -189,9 +151,6 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta files: float64(buf.Files), filesFree: float64(buf.Ffree), ro: ro, - errors: errors, - warnings: warnings, - messages: messages, } } @@ -259,27 +218,4 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) { } return filesystems, scanner.Err() -} - -func readTextFileCounter(filePath string) (float64, error) { - file, err := os.Open(filePath) - if err != nil { - return 0, err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - if scanner.Scan() { - text := scanner.Text() - errorsCount, err := strconv.ParseFloat(text, 64) - if err != nil { - return 0, err - } - return errorsCount, nil - } - - if err := scanner.Err(); err != nil { - return 0, err - } - return 0, errors.New("could not read errors count") -} +} \ No newline at end of file From 7a9dec5f965acdc9e36a89b5b9480fe6829c7632 Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Thu, 11 Jul 2024 05:12:34 +0500 Subject: [PATCH 8/9] Sync filesystem_* package with master --- collector/filesystem_common.go | 2 +- collector/filesystem_linux.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go index 2c89040614..f5d5135241 100644 --- a/collector/filesystem_common.go +++ b/collector/filesystem_common.go @@ -217,4 +217,4 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error { ) } return nil -} \ No newline at end of file +} diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index 64724b3b17..1d0c8493b9 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -218,4 +218,4 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) { } return filesystems, scanner.Err() -} \ No newline at end of file +} From 12a29ee0ca6b95738372d8b832c6a17b551b6c15 Mon Sep 17 00:00:00 2001 From: Muhammad Shahzeb Date: Thu, 11 Jul 2024 05:35:16 +0500 Subject: [PATCH 9/9] Update ext4 collector --- collector/ext4_linux.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/collector/ext4_linux.go b/collector/ext4_linux.go index 9e86c590cf..daac795a47 100644 --- a/collector/ext4_linux.go +++ b/collector/ext4_linux.go @@ -31,12 +31,11 @@ type ext4Collector struct { } func init() { - registerCollector("ext4", defaultEnabled, NewXFSCollector) + registerCollector("ext4", defaultEnabled, NewExt4Collector) } // NewExt4Collector returns a new Collector exposing ext4 statistics. func NewExt4Collector(logger log.Logger) (Collector, error) { - fmt.Printf("**************DEBUG SHAHZEB****************") fs, err := ext4.NewFS(*procPath, *sysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) @@ -108,4 +107,4 @@ func (c *ext4Collector) updateExt4Stats(ch chan<- prometheus.Metric, s *ext4.Sta s.Name, ) } -} \ No newline at end of file +}