From 07c7ae733ad533d6b354fadb58bea03a647e0688 Mon Sep 17 00:00:00 2001 From: Joe Handzik Date: Mon, 23 Jan 2017 12:45:36 -0600 Subject: [PATCH] ZFS Collector: Add fm functionality Signed-Off-By: Joe Handzik --- collector/fixtures/e2e-output.txt | 12 ++++++++ collector/fixtures/proc/spl/kstat/zfs/fm | 6 ++++ collector/zfs.go | 5 ++++ collector/zfs_linux.go | 13 +++++++++ collector/zfs_linux_test.go | 36 ++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 collector/fixtures/proc/spl/kstat/zfs/fm diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt index 9547ca93..3e24780d 100644 --- a/collector/fixtures/e2e-output.txt +++ b/collector/fixtures/e2e-output.txt @@ -2383,6 +2383,18 @@ node_zfsFetch_stride_hits 7.06799e+06 # HELP node_zfsFetch_stride_misses kstat.zfs.misc.zfetchstats.stride_misses # TYPE node_zfsFetch_stride_misses untyped node_zfsFetch_stride_misses 0 +# HELP node_zfsFm_erpt-dropped kstat.zfs.misc.fm.erpt-dropped +# TYPE node_zfsFm_erpt-dropped untyped +node_zfsFm_erpt-dropped 18 +# HELP node_zfsFm_erpt-set-failed kstat.zfs.misc.fm.erpt-set-failed +# TYPE node_zfsFm_erpt-set-failed untyped +node_zfsFm_erpt-set-failed 0 +# HELP node_zfsFm_fmri-set-failed kstat.zfs.misc.fm.fmri-set-failed +# TYPE node_zfsFm_fmri-set-failed untyped +node_zfsFm_fmri-set-failed 0 +# HELP node_zfsFm_payload-set-failed kstat.zfs.misc.fm.payload-set-failed +# TYPE node_zfsFm_payload-set-failed untyped +node_zfsFm_payload-set-failed 0 # HELP node_zfsVdevCache_delegations kstat.zfs.misc.vdev_cache_stats.delegations # TYPE node_zfsVdevCache_delegations untyped node_zfsVdevCache_delegations 40 diff --git a/collector/fixtures/proc/spl/kstat/zfs/fm b/collector/fixtures/proc/spl/kstat/zfs/fm new file mode 100644 index 00000000..c355c0e3 --- /dev/null +++ b/collector/fixtures/proc/spl/kstat/zfs/fm @@ -0,0 +1,6 @@ +0 1 0x01 4 192 8007255140 354329591145385 +name type data +erpt-dropped 4 18 +erpt-set-failed 4 0 +fmri-set-failed 4 0 +payload-set-failed 4 0 diff --git a/collector/zfs.go b/collector/zfs.go index e794090e..138ab11b 100644 --- a/collector/zfs.go +++ b/collector/zfs.go @@ -35,6 +35,7 @@ type zfsSubsystemName string const ( arc = zfsSubsystemName("zfsArc") + fm = zfsSubsystemName("zfsFm") vdevCache = zfsSubsystemName("zfsVdevCache") xuio = zfsSubsystemName("zfsXuio") zfetch = zfsSubsystemName("zfsFetch") @@ -91,6 +92,10 @@ func (c *zfsCollector) Update(ch chan<- prometheus.Metric) (err error) { err = c.updateXuioStats(ch) if err != nil { return err } + // Fm + err = c.updateFm(ch) + if err != nil { return err } + // Pool stats return c.updatePoolStats(ch) } diff --git a/collector/zfs_linux.go b/collector/zfs_linux.go index e8330700..91b014be 100644 --- a/collector/zfs_linux.go +++ b/collector/zfs_linux.go @@ -29,6 +29,7 @@ import ( const ( zfsProcpathBase = "spl/kstat/zfs/" zfsArcstatsExt = "arcstats" + zfsFmExt = "fm" zfsFetchstatsExt = "zfetchstats" zfsVdevCacheStatsExt = "vdev_cache_stats" zfsXuioStatsExt = "xuio_stats" @@ -104,6 +105,18 @@ func (c *zfsCollector) updateXuioStats(ch chan<- prometheus.Metric) (err error) }) } +func (c *zfsCollector) updateFm(ch chan<- prometheus.Metric) (err error) { + file, err := c.openProcFile(filepath.Join(zfsProcpathBase, zfsFmExt)) + if err != nil { + return err + } + defer file.Close() + + return c.parseProcfsFile(file, zfsFmExt, func(s zfsSysctl, v zfsMetricValue) { + ch <- c.constSysctlMetric(fm, s, v) + }) +} + func (c *zfsCollector) parseProcfsFile(reader io.Reader, fmt_ext string, handler func(zfsSysctl, zfsMetricValue)) (err error) { scanner := bufio.NewScanner(reader) diff --git a/collector/zfs_linux_test.go b/collector/zfs_linux_test.go index 82b55a17..ea1229a8 100644 --- a/collector/zfs_linux_test.go +++ b/collector/zfs_linux_test.go @@ -197,3 +197,39 @@ func TestXuioStatsParsing(t *testing.T) { t.Fatal("XuioStats parsing handler was not called for some expected sysctls") } } + +func TestFmParsing(t *testing.T) { + fmFile, err := os.Open("fixtures/proc/spl/kstat/zfs/fm") + if err != nil { + t.Fatal(err) + } + defer fmFile.Close() + + c := zfsCollector{} + if err != nil { + t.Fatal(err) + } + + handlerCalled := false + err = c.parseProcfsFile(fmFile, "fm", func(s zfsSysctl, v zfsMetricValue) { + + if s != zfsSysctl("kstat.zfs.misc.fm.erpt-dropped") { + return + } + + handlerCalled = true + + if v != zfsMetricValue(18) { + t.Fatalf("Incorrect value parsed from procfs data") + } + + }) + + if err != nil { + t.Fatal(err) + } + + if !handlerCalled { + t.Fatal("Fm parsing handler was not called for some expected sysctls") + } +}