Count snapshots per filesystem

This commit is contained in:
Bill Thiede 2017-10-10 19:57:09 -07:00
parent 5171c33d3c
commit e0a0069de4

View File

@ -10,6 +10,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings"
"time" "time"
"github.com/golang/glog" "github.com/golang/glog"
@ -30,25 +31,31 @@ const snapshotListCmd = "/sbin/zfs list -t snapshot -H -o name -s name"
// Example: @auto-20171001.1400-2w // Example: @auto-20171001.1400-2w
var ( var (
snapshotPattern = regexp.MustCompile(`^([^@]+)@auto-(\d{8}\.\d{4})-\d+[mwy]$`) snapshotPattern = regexp.MustCompile(`^[^@]+@auto-(\d{8}\.\d{4})-\d+[mwy]$`)
snapshotFormat = "20060102.1504" snapshotFormat = "20060102.1504"
fetchRequestDurationMetric = prometheus.NewGauge(prometheus.GaugeOpts{ fetchRequestDurationMetric = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "ssh_fetch_duration_seconds", Name: "ssh_fetch_duration_seconds",
Help: "Time to fetch and parse snapshot age over SSH", Help: "Time to fetch and parse snapshot age over SSH",
}) })
snapshotAgesMetric = prometheus.NewGaugeVec( snapshotAgesMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
prometheus.GaugeOpts{ Name: "zfs_snapshot_age_seconds",
Name: "zfs_snapshot_age_seconds", Help: "Duration in seconds for most recent snapshot for `filesystem`",
Help: "Duration in seconds for most recent snapshot for `filesystem`", },
},
[]string{"filesystem"}, []string{"filesystem"},
) )
snapshotCountsMetrics = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "zfs_snapshot_count",
Help: "Count of snapshots per-filesystem",
},
[]string{"filesystem", "type"},
)
) )
func init() { func init() {
prometheus.MustRegister(fetchRequestDurationMetric) prometheus.MustRegister(fetchRequestDurationMetric)
prometheus.MustRegister(snapshotAgesMetric) prometheus.MustRegister(snapshotAgesMetric)
prometheus.MustRegister(snapshotCountsMetrics)
} }
func newPublicKey() ([]ssh.AuthMethod, error) { func newPublicKey() ([]ssh.AuthMethod, error) {
@ -106,20 +113,28 @@ func updateMetrics(c *ssh.Client) error {
return fmt.Errorf("error running %q: %v", snapshotListCmd, err) return fmt.Errorf("error running %q: %v", snapshotListCmd, err)
} }
scanner := bufio.NewScanner(bytes.NewReader(b)) scanner := bufio.NewScanner(bytes.NewReader(b))
snapshotAges := map[string]time.Time{} snapshotAges := make(map[string]time.Time)
snapshotCountsByFilesystem := make(map[string]int)
freenasSnapshotCountsByFilesystem := make(map[string]int)
for scanner.Scan() { for scanner.Scan() {
l := scanner.Text() l := scanner.Text()
m := snapshotPattern.FindStringSubmatch(l) m := snapshotPattern.FindStringSubmatch(l)
if len(m) == 3 {
snapshot := m[1] filesystem := l
t, err := time.Parse(snapshotFormat, m[2]) if idx := strings.Index(l, "@"); idx != -1 {
filesystem = l[:idx]
}
snapshotCountsByFilesystem[filesystem]++
if len(m) == 2 {
t, err := time.Parse(snapshotFormat, m[1])
if err != nil { if err != nil {
glog.Errorf("Malformed time in snapshot %q: %v", m[2], err) glog.Errorf("Malformed time in snapshot %q: %v", m[2], err)
continue continue
} }
snapshotTime := snapshotAges[snapshot] freenasSnapshotCountsByFilesystem[filesystem]++
snapshotTime := snapshotAges[filesystem]
if snapshotTime.Before(t) { if snapshotTime.Before(t) {
snapshotAges[snapshot] = t snapshotAges[filesystem] = t
} }
} }
} }
@ -127,8 +142,14 @@ func updateMetrics(c *ssh.Client) error {
return fmt.Errorf("failed to scan response: %v", err) return fmt.Errorf("failed to scan response: %v", err)
} }
for snapshot, snapshotTime := range snapshotAges { for filesystem, c := range snapshotCountsByFilesystem {
snapshotAgesMetric.WithLabelValues(snapshot).Set(now.Sub(snapshotTime).Seconds()) snapshotCountsMetrics.WithLabelValues(filesystem, "all").Set(float64(c))
}
for filesystem, c := range freenasSnapshotCountsByFilesystem {
snapshotCountsMetrics.WithLabelValues(filesystem, "freenas").Set(float64(c))
}
for filesystem, snapshotTime := range snapshotAges {
snapshotAgesMetric.WithLabelValues(filesystem).Set(now.Sub(snapshotTime).Seconds())
} }
return nil return nil
} }