diff --git a/README.md b/README.md index 69e5500..fc0a84a 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,8 @@ unusable subscription. The ZFS collector discovers all pools on every node and exports their recursive topology with `cluster`, `node`, `pool`, `component`, `path`, and `leaf` labels: -- `pve_node_zfs_state` (`1` for `ONLINE`, otherwise `0`) +- `pve_node_zfs_state` (`0=UNKNOWN`, `1=ONLINE`, `2=DEGRADED`, `3=FAULTED`, + `4=OFFLINE`, `5=REMOVED`, `6=UNAVAIL`) - `pve_node_zfs_read_errors` - `pve_node_zfs_write_errors` - `pve_node_zfs_checksum_errors` diff --git a/metrics/pve_node_zfs_collector.go b/metrics/pve_node_zfs_collector.go index 09b2282..b18e969 100644 --- a/metrics/pve_node_zfs_collector.go +++ b/metrics/pve_node_zfs_collector.go @@ -26,17 +26,26 @@ type zfsMetricComponent struct { Path string } +var zfsStateValues = map[string]float64{ + "ONLINE": 1, + "DEGRADED": 2, + "FAULTED": 3, + "OFFLINE": 4, + "REMOVED": 5, + "UNAVAIL": 6, +} + // NewPveNodeZfsCollector creates a ZFS metrics collector. func NewPveNodeZfsCollector(apiClient *proxmox.PveApiClient, registry *TTLRegistry) *PveNodeZfsCollector { c := PveNodeZfsCollector{apiClient: apiClient, registry: registry} - labelNames := []string{"cluster", "node", "pool", "component", "path", "leaf"} + componentLabelNames := []string{"cluster", "node", "pool", "component", "path", "leaf"} c.state = NewTTLGaugeVec( prometheus.GaugeOpts{ Name: "pve_node_zfs_state", - Help: "ZFS pool component state (1 = ONLINE, 0 = any other state).", + Help: "ZFS pool component state (0 = UNKNOWN, 1 = ONLINE, 2 = DEGRADED, 3 = FAULTED, 4 = OFFLINE, 5 = REMOVED, 6 = UNAVAIL).", }, - labelNames, + componentLabelNames, 5*time.Minute, ) c.registry.Register(c.state) @@ -46,7 +55,7 @@ func NewPveNodeZfsCollector(apiClient *proxmox.PveApiClient, registry *TTLRegist Name: "pve_node_zfs_read_errors", Help: "ZFS pool component read error count.", }, - labelNames, + componentLabelNames, 5*time.Minute, ) c.registry.Register(c.readErrors) @@ -56,7 +65,7 @@ func NewPveNodeZfsCollector(apiClient *proxmox.PveApiClient, registry *TTLRegist Name: "pve_node_zfs_write_errors", Help: "ZFS pool component write error count.", }, - labelNames, + componentLabelNames, 5*time.Minute, ) c.registry.Register(c.writeErrors) @@ -66,7 +75,7 @@ func NewPveNodeZfsCollector(apiClient *proxmox.PveApiClient, registry *TTLRegist Name: "pve_node_zfs_checksum_errors", Help: "ZFS pool component checksum error count.", }, - labelNames, + componentLabelNames, 5*time.Minute, ) c.registry.Register(c.checksumErrors) @@ -146,8 +155,8 @@ func appendZfsComponent(components *[]zfsMetricComponent, component proxmox.PveZ } func zfsStateNumeric(state string) float64 { - if strings.EqualFold(state, "ONLINE") { - return 1 + if value, ok := zfsStateValues[strings.ToUpper(state)]; ok { + return value } return 0 } diff --git a/metrics/pve_node_zfs_collector_test.go b/metrics/pve_node_zfs_collector_test.go index 6f6d951..28b477d 100644 --- a/metrics/pve_node_zfs_collector_test.go +++ b/metrics/pve_node_zfs_collector_test.go @@ -55,10 +55,24 @@ func TestFlattenZfsComponents(t *testing.T) { } func TestZfsStateNumeric(t *testing.T) { - if got := zfsStateNumeric("ONLINE"); got != 1 { - t.Fatalf("zfsStateNumeric(ONLINE) = %v, want 1", got) + tests := []struct { + state string + want float64 + }{ + {state: "UNKNOWN", want: 0}, + {state: "ONLINE", want: 1}, + {state: "DEGRADED", want: 2}, + {state: "FAULTED", want: 3}, + {state: "OFFLINE", want: 4}, + {state: "REMOVED", want: 5}, + {state: "UNAVAIL", want: 6}, } - if got := zfsStateNumeric("DEGRADED"); got != 0 { - t.Fatalf("zfsStateNumeric(DEGRADED) = %v, want 0", got) + + for _, tt := range tests { + t.Run(tt.state, func(t *testing.T) { + if got := zfsStateNumeric(tt.state); got != tt.want { + t.Fatalf("zfsStateNumeric(%q) = %v, want %v", tt.state, got, tt.want) + } + }) } }