master
go 177 lines 4.49 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 //go:build linux || freebsd || openbsd || netbsd || dragonfly
4
5 package zfspool
6
7 import (
8 "fmt"
9 "strings"
10
11 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
12 )
13
14 const (
15 prioZpoolHealthState = 2820 + iota
16 prioVdevHealthState
17
18 prioZpoolSpaceUtilization
19 prioZpoolSpaceUsage
20
21 prioZpoolFragmentation
22 )
23
24 var zpoolChartsTmpl = collectorapi.Charts{
25 zpoolHealthStateChartTmpl.Copy(),
26
27 zpoolSpaceUtilizationChartTmpl.Copy(),
28 zpoolSpaceUsageChartTmpl.Copy(),
29
30 zpoolFragmentationChartTmpl.Copy(),
31 }
32
33 var (
34 zpoolHealthStateChartTmpl = collectorapi.Chart{
35 ID: "zfspool_%s_health_state",
36 Title: "Zpool health state",
37 Units: "state",
38 Fam: "health",
39 Ctx: "zfspool.pool_health_state",
40 Type: collectorapi.Line,
41 Priority: prioZpoolHealthState,
42 Dims: collectorapi.Dims{
43 {ID: "zpool_%s_health_state_online", Name: "online"},
44 {ID: "zpool_%s_health_state_degraded", Name: "degraded"},
45 {ID: "zpool_%s_health_state_faulted", Name: "faulted"},
46 {ID: "zpool_%s_health_state_offline", Name: "offline"},
47 {ID: "zpool_%s_health_state_unavail", Name: "unavail"},
48 {ID: "zpool_%s_health_state_removed", Name: "removed"},
49 {ID: "zpool_%s_health_state_suspended", Name: "suspended"},
50 },
51 }
52
53 zpoolSpaceUtilizationChartTmpl = collectorapi.Chart{
54 ID: "zfspool_%s_space_utilization",
55 Title: "Zpool space utilization",
56 Units: "percentage",
57 Fam: "space usage",
58 Ctx: "zfspool.pool_space_utilization",
59 Type: collectorapi.Area,
60 Priority: prioZpoolSpaceUtilization,
61 Dims: collectorapi.Dims{
62 {ID: "zpool_%s_cap", Name: "utilization"},
63 },
64 }
65 zpoolSpaceUsageChartTmpl = collectorapi.Chart{
66 ID: "zfspool_%s_space_usage",
67 Title: "Zpool space usage",
68 Units: "bytes",
69 Fam: "space usage",
70 Ctx: "zfspool.pool_space_usage",
71 Type: collectorapi.Stacked,
72 Priority: prioZpoolSpaceUsage,
73 Dims: collectorapi.Dims{
74 {ID: "zpool_%s_free", Name: "free"},
75 {ID: "zpool_%s_alloc", Name: "used"},
76 },
77 }
78
79 zpoolFragmentationChartTmpl = collectorapi.Chart{
80 ID: "zfspool_%s_fragmentation",
81 Title: "Zpool fragmentation",
82 Units: "percentage",
83 Fam: "fragmentation",
84 Ctx: "zfspool.pool_fragmentation",
85 Type: collectorapi.Line,
86 Priority: prioZpoolFragmentation,
87 Dims: collectorapi.Dims{
88 {ID: "zpool_%s_frag", Name: "fragmentation"},
89 },
90 }
91 )
92
93 var vdevChartsTmpl = collectorapi.Charts{
94 vdevHealthStateChartTmpl.Copy(),
95 }
96
97 var (
98 vdevHealthStateChartTmpl = collectorapi.Chart{
99 ID: "vdev_%s_health_state",
100 Title: "Zpool Vdev health state",
101 Units: "state",
102 Fam: "health",
103 Ctx: "zfspool.vdev_health_state",
104 Type: collectorapi.Line,
105 Priority: prioVdevHealthState,
106 Dims: collectorapi.Dims{
107 {ID: "vdev_%s_health_state_online", Name: "online"},
108 {ID: "vdev_%s_health_state_degraded", Name: "degraded"},
109 {ID: "vdev_%s_health_state_faulted", Name: "faulted"},
110 {ID: "vdev_%s_health_state_offline", Name: "offline"},
111 {ID: "vdev_%s_health_state_unavail", Name: "unavail"},
112 {ID: "vdev_%s_health_state_removed", Name: "removed"},
113 {ID: "vdev_%s_health_state_suspended", Name: "suspended"},
114 },
115 }
116 )
117
118 func (c *Collector) addZpoolCharts(name string) {
119 charts := zpoolChartsTmpl.Copy()
120
121 for _, chart := range *charts {
122 chart.ID = fmt.Sprintf(chart.ID, name)
123 chart.Labels = []collectorapi.Label{
124 {Key: "pool", Value: name},
125 }
126 for _, dim := range chart.Dims {
127 dim.ID = fmt.Sprintf(dim.ID, name)
128 }
129 }
130
131 if err := c.Charts().Add(*charts...); err != nil {
132 c.Warning(err)
133 }
134 }
135
136 func (c *Collector) removeZpoolCharts(name string) {
137 px := fmt.Sprintf("zfspool_%s_", name)
138 c.removeCharts(px)
139 }
140
141 func (c *Collector) addVdevCharts(pool, vdev string) {
142 charts := vdevChartsTmpl.Copy()
143
144 for _, chart := range *charts {
145 chart.ID = fmt.Sprintf(chart.ID, cleanVdev(vdev))
146 chart.Labels = []collectorapi.Label{
147 {Key: "pool", Value: pool},
148 {Key: "vdev", Value: vdev},
149 }
150 for _, dim := range chart.Dims {
151 dim.ID = fmt.Sprintf(dim.ID, vdev)
152 }
153 }
154
155 if err := c.Charts().Add(*charts...); err != nil {
156 c.Warning(err)
157 }
158 }
159
160 func (c *Collector) removeVdevCharts(vdev string) {
161 px := fmt.Sprintf("vdev_%s_", cleanVdev(vdev))
162 c.removeCharts(px)
163 }
164
165 func (c *Collector) removeCharts(px string) {
166 for _, chart := range *c.Charts() {
167 if strings.HasPrefix(chart.ID, px) {
168 chart.MarkRemove()
169 chart.MarkNotCreated()
170 }
171 }
172 }
173
174 func cleanVdev(vdev string) string {
175 r := strings.NewReplacer(".", "_")
176 return r.Replace(vdev)
177 }