From 7ae07d544790485996674a983996147078090570 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sun, 15 Jan 2023 11:04:52 -0800 Subject: [PATCH] Add support for linux snapshot naming pattern. --- zfs_replication_exporter.go | 47 ++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/zfs_replication_exporter.go b/zfs_replication_exporter.go index 528b23f..4c57075 100644 --- a/zfs_replication_exporter.go +++ b/zfs_replication_exporter.go @@ -32,9 +32,21 @@ var ( const snapshotListCmd = "/sbin/zfs list -t snapshot -H -o name -s name" var ( - // Example: @auto-20171001.1400-2w - snapshotPattern = regexp.MustCompile(`^[^@]+@auto-(\d{8}\.\d{4})-\d+[mwy]$`) - snapshotFormat = "20060102.1504" + // FreeNAS example: + // @auto-20171001.1400-2w + freenasSnapshotPattern = regexp.MustCompile(`^[^@]+@auto-(\d{8}\.\d{4})-\d+[mwy]$`) + // Linux examples: + // @zfs-auto-snap_frequent-2023-01-15-18h00U + // @zfs-auto-snap_frequent-2023-01-15-18h15U + // @zfs-auto-snap_frequent-2023-01-15-18h30U + // @zfs-auto-snap_frequent-2023-01-15-18h45U + // @zfs-auto-snap_daily-2023-01-14-08h00U + // @zfs-auto-snap_hourly-2023-01-14-19h00U + // @zfs-auto-snap_weekly-2022-12-19-08h00U + // @zfs-auto-snap_monthly-2022-12-01-08h00U + linuxSnapshotPattern = regexp.MustCompile(`^[^@]+@zfs-auto-snap_(?:frequent|daily|hourly|weekly|monthly)-(\d{4}-\d{2}-\d{2}-\d{2}h\d{2}U)$`) + freenasSnapshotFormat = "20060102.1504" + linuxSnapshotFormat = "2006-01-02-15h04U" fetchRequestDurationMetric = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "ssh_fetch_duration_seconds", @@ -130,8 +142,6 @@ func fetchSnapshotStats(host string, c *ssh.Client) (snapshotStats, error) { stats := snapshotStats(make(map[filesystemName]*filesystemStat)) for scanner.Scan() { l := scanner.Text() - m := snapshotPattern.FindStringSubmatch(l) - filesystem := l if idx := strings.Index(l, "@"); idx != -1 { filesystem = l[:idx] @@ -141,10 +151,13 @@ func fetchSnapshotStats(host string, c *ssh.Client) (snapshotStats, error) { stats[name] = &filesystemStat{} } stats[name].Counts++ - if len(m) == 2 { - t, err := time.Parse(snapshotFormat, m[1]) + + var foundSnapshot bool + if m := freenasSnapshotPattern.FindStringSubmatch(l); len(m) == 2 { + foundSnapshot = true + t, err := time.Parse(freenasSnapshotFormat, m[1]) if err != nil { - glog.Errorf("[%s] Malformed time in snapshot %q: %v", host, m[1], err) + glog.Errorf("[%s] Malformed time in freenas snapshot %q: %v", host, m[1], err) continue } glog.V(3).Infof("filesystem: %s timestamp %v", l, t) @@ -154,7 +167,23 @@ func fetchSnapshotStats(host string, c *ssh.Client) (snapshotStats, error) { if snapshotTime.Before(t) { stats[name].Timestamp = t } - } else { + } + if m := linuxSnapshotPattern.FindStringSubmatch(l); len(m) == 2 { + foundSnapshot = true + t, err := time.Parse(linuxSnapshotFormat, m[1]) + if err != nil { + glog.Errorf("[%s] Malformed time in linux snapshot %q: %v", host, m[1], err) + continue + } + glog.V(3).Infof("filesystem: %s timestamp %v", l, t) + stats[name].FreenasCounts++ + snapshotTime := stats[name].Timestamp + glog.V(3).Infof("snapshotTime.Before(t) = %v snapshotTime: %v t: %v", snapshotTime.Before(t), snapshotTime, t) + if snapshotTime.Before(t) { + stats[name].Timestamp = t + } + } + if !foundSnapshot { glog.V(3).Infof("[%s] Skipping snapshot with non-conforming timestamp %q", host, l) } }