master
go 465 lines 12.8 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package scaleio
4
5 import (
6 "fmt"
7
8 "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/scaleio/client"
9
10 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
11 )
12
13 type (
14 // Charts is an alias for collectorapi.Charts.
15 Charts = collectorapi.Charts
16 // Dims is an alias for collectorapi.Dims.
17 Dims = collectorapi.Dims
18 // Vars is an alias for collectorapi.Vars.
19 Vars = collectorapi.Vars
20 )
21
22 var (
23 prioStoragePool = collectorapi.Priority + len(systemCharts) + 10
24 prioSdc = prioStoragePool + len(storagePoolCharts) + 10
25 )
26
27 var systemCharts = Charts{
28 // Capacity
29 {
30 ID: "system_capacity_total",
31 Title: "Total Capacity",
32 Units: "KiB",
33 Fam: "capacity",
34 Ctx: "scaleio.system_capacity_total",
35 Dims: Dims{
36 {ID: "system_capacity_max_capacity", Name: "total"},
37 },
38 },
39 {
40 ID: "system_capacity_in_use",
41 Title: "Capacity In Use",
42 Units: "KiB",
43 Fam: "capacity",
44 Ctx: "scaleio.system_capacity_in_use",
45 Dims: Dims{
46 {ID: "system_capacity_in_use", Name: "in_use"},
47 },
48 },
49 {
50 ID: "system_capacity_usage",
51 Title: "Capacity Usage",
52 Units: "KiB",
53 Fam: "capacity",
54 Type: collectorapi.Stacked,
55 Ctx: "scaleio.system_capacity_usage",
56 Dims: Dims{
57 {ID: "system_capacity_thick_in_use", Name: "thick"},
58 {ID: "system_capacity_decreased", Name: "decreased"},
59 {ID: "system_capacity_thin_in_use", Name: "thin"},
60 {ID: "system_capacity_snapshot", Name: "snapshot"},
61 {ID: "system_capacity_spare", Name: "spare"},
62 {ID: "system_capacity_unused", Name: "unused"},
63 },
64 },
65 {
66 ID: "system_capacity_available_volume_allocation",
67 Title: "Available For Volume Allocation",
68 Units: "KiB",
69 Fam: "capacity",
70 Ctx: "scaleio.system_capacity_available_volume_allocation",
71 Dims: Dims{
72 {ID: "system_capacity_available_for_volume_allocation", Name: "available"},
73 },
74 },
75 {
76 ID: "system_capacity_health_state",
77 Title: "Capacity Health State",
78 Units: "KiB",
79 Fam: "health",
80 Type: collectorapi.Stacked,
81 Ctx: "scaleio.system_capacity_health_state",
82 Dims: Dims{
83 {ID: "system_capacity_protected", Name: "protected"},
84 {ID: "system_capacity_degraded", Name: "degraded"},
85 {ID: "system_capacity_in_maintenance", Name: "in_maintenance"},
86 {ID: "system_capacity_failed", Name: "failed"},
87 {ID: "system_capacity_unreachable_unused", Name: "unavailable"},
88 },
89 },
90 // I/O Workload BW
91 {
92 ID: "system_workload_primary_bandwidth_total",
93 Title: "Primary Backend Bandwidth Total (Read and Write)",
94 Units: "KiB/s",
95 Fam: "workload",
96 Ctx: "scaleio.system_workload_primary_bandwidth_total",
97 Dims: Dims{
98 {ID: "system_backend_primary_bandwidth_read_write", Name: "total", Div: 1000},
99 },
100 },
101 {
102 ID: "system_workload_primary_bandwidth",
103 Title: "Primary Backend Bandwidth",
104 Units: "KiB/s",
105 Fam: "workload",
106 Ctx: "scaleio.system_workload_primary_bandwidth",
107 Type: collectorapi.Area,
108 Dims: Dims{
109 {ID: "system_backend_primary_bandwidth_read", Name: "read", Div: 1000},
110 {ID: "system_backend_primary_bandwidth_write", Name: "write", Mul: -1, Div: 1000},
111 },
112 },
113 // I/O Workload IOPS
114 {
115 ID: "system_workload_primary_iops_total",
116 Title: "Primary Backend IOPS Total (Read and Write)",
117 Units: "iops/s",
118 Fam: "workload",
119 Ctx: "scaleio.system_workload_primary_iops_total",
120 Dims: Dims{
121 {ID: "system_backend_primary_iops_read_write", Name: "total", Div: 1000},
122 },
123 },
124 {
125 ID: "system_workload_primary_iops",
126 Title: "Primary Backend IOPS",
127 Units: "iops/s",
128 Fam: "workload",
129 Ctx: "scaleio.system_workload_primary_iops",
130 Type: collectorapi.Area,
131 Dims: Dims{
132 {ID: "system_backend_primary_iops_read", Name: "read", Div: 1000},
133 {ID: "system_backend_primary_iops_write", Name: "write", Mul: -1, Div: 1000},
134 },
135 },
136 {
137 ID: "system_workload_primary_io_size_total",
138 Title: "Primary Backend I/O Size Total (Read and Write)",
139 Units: "KiB",
140 Fam: "workload",
141 Ctx: "scaleio.system_workload_primary_io_size_total",
142 Dims: Dims{
143 {ID: "system_backend_primary_io_size_read_write", Name: "io_size", Div: 1000},
144 },
145 },
146 // Rebalance
147 {
148 ID: "system_rebalance",
149 Title: "Rebalance",
150 Units: "KiB/s",
151 Fam: "rebalance",
152 Type: collectorapi.Area,
153 Ctx: "scaleio.system_rebalance",
154 Dims: Dims{
155 {ID: "system_rebalance_bandwidth_read", Name: "read", Div: 1000},
156 {ID: "system_rebalance_bandwidth_write", Name: "write", Mul: -1, Div: 1000},
157 },
158 },
159 {
160 ID: "system_rebalance_left",
161 Title: "Rebalance Pending Capacity",
162 Units: "KiB",
163 Fam: "rebalance",
164 Ctx: "scaleio.system_rebalance_left",
165 Dims: Dims{
166 {ID: "system_rebalance_pending_capacity_in_Kb", Name: "left"},
167 },
168 },
169 {
170 ID: "system_rebalance_time_until_finish",
171 Title: "Rebalance Approximate Time Until Finish",
172 Units: "seconds",
173 Fam: "rebalance",
174 Ctx: "scaleio.system_rebalance_time_until_finish",
175 Dims: Dims{
176 {ID: "system_rebalance_time_until_finish", Name: "time"},
177 },
178 },
179 // Rebuild
180 {
181 ID: "system_rebuild",
182 Title: "Rebuild Bandwidth Total (Forward, Backward and Normal)",
183 Units: "KiB/s",
184 Fam: "rebuild",
185 Ctx: "scaleio.system_rebuild",
186 Type: collectorapi.Area,
187 Dims: Dims{
188 {ID: "system_rebuild_total_bandwidth_read", Name: "read", Div: 1000},
189 {ID: "system_rebuild_total_bandwidth_write", Name: "write", Mul: -1, Div: 1000},
190 },
191 },
192 {
193 ID: "system_rebuild_left",
194 Title: "Rebuild Pending Capacity Total (Forward, Backward and Normal)",
195 Units: "KiB",
196 Fam: "rebuild",
197 Ctx: "scaleio.system_rebuild_left",
198 Dims: Dims{
199 {ID: "system_rebuild_total_pending_capacity_in_Kb", Name: "left"},
200 },
201 },
202 // Components
203 {
204 ID: "system_defined_components",
205 Title: "Components",
206 Units: "components",
207 Fam: "components",
208 Ctx: "scaleio.system_defined_components",
209 Dims: Dims{
210 {ID: "system_num_of_devices", Name: "devices"},
211 {ID: "system_num_of_fault_sets", Name: "fault_sets"},
212 {ID: "system_num_of_protection_domains", Name: "protection_domains"},
213 {ID: "system_num_of_rfcache_devices", Name: "rfcache_devices"},
214 {ID: "system_num_of_sdc", Name: "sdc"},
215 {ID: "system_num_of_sds", Name: "sds"},
216 {ID: "system_num_of_snapshots", Name: "snapshots"},
217 {ID: "system_num_of_storage_pools", Name: "storage_pools"},
218 {ID: "system_num_of_volumes", Name: "volumes"},
219 {ID: "system_num_of_vtrees", Name: "vtrees"},
220 },
221 },
222 {
223 ID: "system_components_volumes_by_type",
224 Title: "Volumes By Type",
225 Units: "volumes",
226 Fam: "components",
227 Ctx: "scaleio.system_components_volumes_by_type",
228 Type: collectorapi.Stacked,
229 Dims: Dims{
230 {ID: "system_num_of_thick_base_volumes", Name: "thick"},
231 {ID: "system_num_of_thin_base_volumes", Name: "thin"},
232 },
233 },
234 {
235 ID: "system_components_volumes_by_mapping",
236 Title: "Volumes By Mapping",
237 Units: "volumes",
238 Fam: "components",
239 Ctx: "scaleio.system_components_volumes_by_mapping",
240 Type: collectorapi.Stacked,
241 Dims: Dims{
242 {ID: "system_num_of_mapped_volumes", Name: "mapped"},
243 {ID: "system_num_of_unmapped_volumes", Name: "unmapped"},
244 },
245 },
246 }
247
248 var storagePoolCharts = Charts{
249 {
250 ID: "storage_pool_%s_capacity_total",
251 Title: "Total Capacity",
252 Units: "KiB",
253 Fam: "pool %s",
254 Ctx: "scaleio.storage_pool_capacity_total",
255 Dims: Dims{
256 {ID: "storage_pool_%s_capacity_max_capacity", Name: "total"},
257 },
258 },
259 {
260 ID: "storage_pool_%s_capacity_in_use",
261 Title: "Capacity In Use",
262 Units: "KiB",
263 Fam: "pool %s",
264 Ctx: "scaleio.storage_pool_capacity_in_use",
265 Dims: Dims{
266 {ID: "storage_pool_%s_capacity_in_use", Name: "in_use"},
267 },
268 },
269 {
270 ID: "storage_pool_%s_capacity_usage",
271 Title: "Capacity Usage",
272 Units: "KiB",
273 Fam: "pool %s",
274 Type: collectorapi.Stacked,
275 Ctx: "scaleio.storage_pool_capacity_usage",
276 Dims: Dims{
277 {ID: "storage_pool_%s_capacity_thick_in_use", Name: "thick"},
278 {ID: "storage_pool_%s_capacity_decreased", Name: "decreased"},
279 {ID: "storage_pool_%s_capacity_thin_in_use", Name: "thin"},
280 {ID: "storage_pool_%s_capacity_snapshot", Name: "snapshot"},
281 {ID: "storage_pool_%s_capacity_spare", Name: "spare"},
282 {ID: "storage_pool_%s_capacity_unused", Name: "unused"},
283 },
284 },
285 {
286 ID: "storage_pool_%s_capacity_utilization",
287 Title: "Capacity Utilization",
288 Units: "percentage",
289 Fam: "pool %s",
290 Ctx: "scaleio.storage_pool_capacity_utilization",
291 Dims: Dims{
292 {ID: "storage_pool_%s_capacity_utilization", Name: "used", Div: 100},
293 },
294 Vars: Vars{
295 {ID: "storage_pool_%s_capacity_alert_high_threshold"},
296 {ID: "storage_pool_%s_capacity_alert_critical_threshold"},
297 },
298 },
299 {
300 ID: "storage_pool_%s_capacity_available_volume_allocation",
301 Title: "Available For Volume Allocation",
302 Units: "KiB",
303 Fam: "pool %s",
304 Ctx: "scaleio.storage_pool_capacity_available_volume_allocation",
305 Dims: Dims{
306 {ID: "storage_pool_%s_capacity_available_for_volume_allocation", Name: "available"},
307 },
308 },
309 {
310 ID: "storage_pool_%s_capacity_health_state",
311 Title: "Capacity Health State",
312 Units: "KiB",
313 Fam: "pool %s",
314 Type: collectorapi.Stacked,
315 Ctx: "scaleio.storage_pool_capacity_health_state",
316 Dims: Dims{
317 {ID: "storage_pool_%s_capacity_protected", Name: "protected"},
318 {ID: "storage_pool_%s_capacity_degraded", Name: "degraded"},
319 {ID: "storage_pool_%s_capacity_in_maintenance", Name: "in_maintenance"},
320 {ID: "storage_pool_%s_capacity_failed", Name: "failed"},
321 {ID: "storage_pool_%s_capacity_unreachable_unused", Name: "unavailable"},
322 },
323 },
324 {
325 ID: "storage_pool_%s_components",
326 Title: "Components",
327 Units: "components",
328 Fam: "pool %s",
329 Ctx: "scaleio.storage_pool_components",
330 Dims: Dims{
331 {ID: "storage_pool_%s_num_of_devices", Name: "devices"},
332 {ID: "storage_pool_%s_num_of_snapshots", Name: "snapshots"},
333 {ID: "storage_pool_%s_num_of_volumes", Name: "volumes"},
334 {ID: "storage_pool_%s_num_of_vtrees", Name: "vtrees"},
335 },
336 },
337 }
338
339 func newStoragePoolCharts(pool client.StoragePool) *Charts {
340 charts := storagePoolCharts.Copy()
341 for i, chart := range *charts {
342 chart.ID = fmt.Sprintf(chart.ID, pool.ID)
343 chart.Fam = fmt.Sprintf(chart.Fam, pool.Name)
344 chart.Priority = prioStoragePool + i
345 for _, dim := range chart.Dims {
346 dim.ID = fmt.Sprintf(dim.ID, pool.ID)
347 }
348 for _, v := range chart.Vars {
349 v.ID = fmt.Sprintf(v.ID, pool.ID)
350 }
351 }
352 return charts
353 }
354
355 var sdcCharts = Charts{
356 {
357 ID: "sdc_%s_mdm_connection_state",
358 Title: "MDM Connection State",
359 Units: "boolean",
360 Fam: "sdc %s",
361 Ctx: "scaleio.sdc_mdm_connection_state",
362 Dims: Dims{
363 {ID: "sdc_%s_mdm_connection_state", Name: "connected"},
364 },
365 },
366 {
367 ID: "sdc_%s_bandwidth",
368 Title: "Bandwidth",
369 Units: "KiB/s",
370 Fam: "sdc %s",
371 Ctx: "scaleio.sdc_bandwidth",
372 Type: collectorapi.Area,
373 Dims: Dims{
374 {ID: "sdc_%s_bandwidth_read", Name: "read", Div: 1000},
375 {ID: "sdc_%s_bandwidth_write", Name: "write", Mul: -1, Div: 1000},
376 },
377 },
378 {
379 ID: "sdc_%s_iops",
380 Title: "IOPS",
381 Units: "iops/s",
382 Fam: "sdc %s",
383 Ctx: "scaleio.sdc_iops",
384 Type: collectorapi.Area,
385 Dims: Dims{
386 {ID: "sdc_%s_iops_read", Name: "read", Div: 1000},
387 {ID: "sdc_%s_iops_write", Name: "write", Mul: -1, Div: 1000},
388 },
389 },
390 {
391 ID: "sdc_%s_io_size",
392 Title: "I/O Size",
393 Units: "KiB",
394 Fam: "sdc %s",
395 Ctx: "scaleio.sdc_io_size",
396 Type: collectorapi.Area,
397 Dims: Dims{
398 {ID: "sdc_%s_io_size_read", Name: "read", Div: 1000},
399 {ID: "sdc_%s_io_size_write", Name: "write", Mul: -1, Div: 1000},
400 },
401 },
402 {
403 ID: "sdc_%s_num_of_mapped_volumed",
404 Title: "Mapped Volumes",
405 Units: "volumes",
406 Fam: "sdc %s",
407 Ctx: "scaleio.sdc_num_of_mapped_volumed",
408 Dims: Dims{
409 {ID: "sdc_%s_num_of_mapped_volumes", Name: "mapped"},
410 },
411 },
412 }
413
414 func newSdcCharts(sdc client.Sdc) *Charts {
415 charts := sdcCharts.Copy()
416 for i, chart := range *charts {
417 chart.ID = fmt.Sprintf(chart.ID, sdc.ID)
418 chart.Fam = fmt.Sprintf(chart.Fam, sdc.SdcIp)
419 chart.Priority = prioSdc + i
420 for _, dim := range chart.Dims {
421 dim.ID = fmt.Sprintf(dim.ID, sdc.ID)
422 }
423 }
424 return charts
425 }
426
427 // TODO: remove stale charts?
428 func (c *Collector) updateCharts() {
429 c.updateStoragePoolCharts()
430 c.updateSdcCharts()
431 }
432
433 func (c *Collector) updateStoragePoolCharts() {
434 for _, pool := range c.discovered.pool {
435 if c.charted[pool.ID] {
436 continue
437 }
438 c.charted[pool.ID] = true
439 c.addStoragePoolCharts(pool)
440 }
441 }
442
443 func (c *Collector) updateSdcCharts() {
444 for _, sdc := range c.discovered.sdc {
445 if c.charted[sdc.ID] {
446 continue
447 }
448 c.charted[sdc.ID] = true
449 c.addSdcCharts(sdc)
450 }
451 }
452
453 func (c *Collector) addStoragePoolCharts(pool client.StoragePool) {
454 charts := newStoragePoolCharts(pool)
455 if err := c.Charts().Add(*charts...); err != nil {
456 c.Warningf("couldn't add charts for storage pool '%s(%s)': %v", pool.ID, pool.Name, err)
457 }
458 }
459
460 func (c *Collector) addSdcCharts(sdc client.Sdc) {
461 charts := newSdcCharts(sdc)
462 if err := c.Charts().Add(*charts...); err != nil {
463 c.Warningf("couldn't add charts for sdc '%s(%s)': %v", sdc.ID, sdc.SdcIp, err)
464 }
465 }