| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package ceph |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "strings" |
| 8 | |
| 9 | "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi" |
| 10 | ) |
| 11 | |
| 12 | const ( |
| 13 | prioClusterStatus = collectorapi.Priority + iota |
| 14 | prioClusterHostsCount |
| 15 | prioClusterMonitorsCount |
| 16 | prioClusterOSDsCount |
| 17 | prioClusterOSDsByStatusCount |
| 18 | prioClusterManagersCount |
| 19 | prioClusterObjectGatewaysCount |
| 20 | prioClusterIScsiGatewaysCount |
| 21 | prioClusterIScsiGatewaysByStatusCount |
| 22 | |
| 23 | prioClusterPhysCapacityUtilization |
| 24 | prioClusterPhysCapacityUsage |
| 25 | prioClusterObjectsCount |
| 26 | prioClusterObjectsByStatusPercent |
| 27 | prioClusterPoolsCount |
| 28 | prioClusterPGsCount |
| 29 | prioClusterPGsByStatusCount |
| 30 | prioClusterPGsPerOsdCount |
| 31 | |
| 32 | prioClusterClientIO |
| 33 | prioClusterClientIOPS |
| 34 | prioClusterClientRecoveryThroughput |
| 35 | prioClusterScrubStatus |
| 36 | |
| 37 | prioOsdStatus |
| 38 | prioOsdSpaceUsage |
| 39 | prioOsdIO |
| 40 | prioOsdIOPS |
| 41 | prioOsdLatency |
| 42 | |
| 43 | prioPoolSpaceUtilization |
| 44 | prioPoolSpaceUsage |
| 45 | prioPoolObjectsCount |
| 46 | prioPoolIO |
| 47 | prioPoolIOPS |
| 48 | ) |
| 49 | |
| 50 | var clusterCharts = collectorapi.Charts{ |
| 51 | clusterStatusChart.Copy(), |
| 52 | clusterHostsCountChart.Copy(), |
| 53 | clusterMonitorsCountChart.Copy(), |
| 54 | clusterOsdsCountChart.Copy(), |
| 55 | clusterOsdsByStatusCountChart.Copy(), |
| 56 | clusterManagersCountChart.Copy(), |
| 57 | clusterObjectGatewaysCountChart.Copy(), |
| 58 | clusterIScsiGatewaysCountChart.Copy(), |
| 59 | clusterIScsiGatewaysByStatusCountChart.Copy(), |
| 60 | |
| 61 | clusterPhysCapacityUtilizationChart.Copy(), |
| 62 | clusterPhysCapacityUsageChart.Copy(), |
| 63 | clusterObjectsCountChart.Copy(), |
| 64 | clusterObjectsByStatusPercentChart.Copy(), |
| 65 | clusterPoolsCountChart.Copy(), |
| 66 | clusterPGsCountChart.Copy(), |
| 67 | clusterPGsByStatusCountChart.Copy(), |
| 68 | clusterPgsPerOsdCountChart.Copy(), |
| 69 | |
| 70 | clusterClientIOChart.Copy(), |
| 71 | clusterClientIOPSChart.Copy(), |
| 72 | clusterRecoveryThroughputChart.Copy(), |
| 73 | clusterScrubStatusChart.Copy(), |
| 74 | } |
| 75 | |
| 76 | var osdChartsTmpl = collectorapi.Charts{ |
| 77 | osdStatusChartTmpl.Copy(), |
| 78 | osdSpaceUsageChartTmpl.Copy(), |
| 79 | osdIOChartTmpl.Copy(), |
| 80 | osdIOPSChartTmpl.Copy(), |
| 81 | osdLatencyChartTmpl.Copy(), |
| 82 | } |
| 83 | |
| 84 | var poolChartsTmpl = collectorapi.Charts{ |
| 85 | poolSpaceUtilizationChartTmpl.Copy(), |
| 86 | poolSpaceUsageChartTmpl.Copy(), |
| 87 | poolObjectsCountChartTmpl.Copy(), |
| 88 | poolIOChartTmpl.Copy(), |
| 89 | poolIOPSChartTmpl.Copy(), |
| 90 | } |
| 91 | |
| 92 | var ( |
| 93 | clusterStatusChart = collectorapi.Chart{ |
| 94 | ID: "cluster_status", |
| 95 | Title: "Ceph Cluster Status", |
| 96 | Fam: "status", |
| 97 | Units: "status", |
| 98 | Ctx: "ceph.cluster_status", |
| 99 | Type: collectorapi.Line, |
| 100 | Priority: prioClusterStatus, |
| 101 | Dims: collectorapi.Dims{ |
| 102 | {ID: "health_ok", Name: "ok"}, |
| 103 | {ID: "health_err", Name: "err"}, |
| 104 | {ID: "health_warn", Name: "warn"}, |
| 105 | }, |
| 106 | } |
| 107 | clusterHostsCountChart = collectorapi.Chart{ |
| 108 | ID: "cluster_hosts_count", |
| 109 | Title: "Ceph Cluster Hosts", |
| 110 | Fam: "status", |
| 111 | Units: "hosts", |
| 112 | Ctx: "ceph.cluster_hosts_count", |
| 113 | Type: collectorapi.Line, |
| 114 | Priority: prioClusterHostsCount, |
| 115 | Dims: collectorapi.Dims{ |
| 116 | {ID: "hosts_num", Name: "hosts"}, |
| 117 | }, |
| 118 | } |
| 119 | clusterMonitorsCountChart = collectorapi.Chart{ |
| 120 | ID: "cluster_monitors_count", |
| 121 | Title: "Ceph Cluster Monitors", |
| 122 | Fam: "status", |
| 123 | Units: "monitors", |
| 124 | Ctx: "ceph.cluster_monitors_count", |
| 125 | Type: collectorapi.Line, |
| 126 | Priority: prioClusterMonitorsCount, |
| 127 | Dims: collectorapi.Dims{ |
| 128 | {ID: "monitors_num", Name: "monitors"}, |
| 129 | }, |
| 130 | } |
| 131 | clusterOsdsCountChart = collectorapi.Chart{ |
| 132 | ID: "cluster_osds_count", |
| 133 | Title: "Ceph Cluster OSDs", |
| 134 | Fam: "status", |
| 135 | Units: "osds", |
| 136 | Ctx: "ceph.cluster_osds_count", |
| 137 | Type: collectorapi.Line, |
| 138 | Priority: prioClusterOSDsCount, |
| 139 | Dims: collectorapi.Dims{ |
| 140 | {ID: "osds_num", Name: "osds"}, |
| 141 | }, |
| 142 | } |
| 143 | clusterOsdsByStatusCountChart = collectorapi.Chart{ |
| 144 | ID: "cluster_osds_by_status_count", |
| 145 | Title: "Ceph Cluster OSDs by Status", |
| 146 | Fam: "status", |
| 147 | Units: "osds", |
| 148 | Ctx: "ceph.cluster_osds_by_status_count", |
| 149 | Type: collectorapi.Line, |
| 150 | Priority: prioClusterOSDsByStatusCount, |
| 151 | Dims: collectorapi.Dims{ |
| 152 | {ID: "osds_up_num", Name: "up"}, |
| 153 | {ID: "osds_down_num", Name: "down"}, |
| 154 | {ID: "osds_in_num", Name: "in"}, |
| 155 | {ID: "osds_out_num", Name: "out"}, |
| 156 | }, |
| 157 | } |
| 158 | clusterManagersCountChart = collectorapi.Chart{ |
| 159 | ID: "cluster_managers_count", |
| 160 | Title: "Ceph Cluster Managers", |
| 161 | Fam: "status", |
| 162 | Units: "managers", |
| 163 | Ctx: "ceph.cluster_managers_count", |
| 164 | Type: collectorapi.Line, |
| 165 | Priority: prioClusterManagersCount, |
| 166 | Dims: collectorapi.Dims{ |
| 167 | {ID: "mgr_active_num", Name: "active"}, |
| 168 | {ID: "mgr_standby_num", Name: "standby"}, |
| 169 | }, |
| 170 | } |
| 171 | clusterObjectGatewaysCountChart = collectorapi.Chart{ |
| 172 | ID: "cluster_object_gateways_count", |
| 173 | Title: "Ceph Cluster Object Gateways (RGW)", |
| 174 | Fam: "status", |
| 175 | Units: "gateways", |
| 176 | Ctx: "ceph.cluster_object_gateways_count", |
| 177 | Type: collectorapi.Line, |
| 178 | Priority: prioClusterObjectGatewaysCount, |
| 179 | Dims: collectorapi.Dims{ |
| 180 | {ID: "rgw_num", Name: "object"}, |
| 181 | }, |
| 182 | } |
| 183 | clusterIScsiGatewaysCountChart = collectorapi.Chart{ |
| 184 | ID: "cluster_iscsi_gateways_count", |
| 185 | Title: "Ceph Cluster iSCSI Gateways", |
| 186 | Fam: "status", |
| 187 | Units: "gateways", |
| 188 | Ctx: "ceph.cluster_iscsi_gateways_count", |
| 189 | Type: collectorapi.Line, |
| 190 | Priority: prioClusterIScsiGatewaysCount, |
| 191 | Dims: collectorapi.Dims{ |
| 192 | {ID: "iscsi_daemons_num", Name: "iscsi"}, |
| 193 | }, |
| 194 | } |
| 195 | clusterIScsiGatewaysByStatusCountChart = collectorapi.Chart{ |
| 196 | ID: "cluster_iscsi_gateways_by_status_count", |
| 197 | Title: "Ceph Cluster iSCSI Gateways by Status", |
| 198 | Fam: "status", |
| 199 | Units: "gateways", |
| 200 | Ctx: "ceph.cluster_iscsi_gateways_by_status_count", |
| 201 | Type: collectorapi.Line, |
| 202 | Priority: prioClusterIScsiGatewaysByStatusCount, |
| 203 | Dims: collectorapi.Dims{ |
| 204 | {ID: "iscsi_daemons_up_num", Name: "up"}, |
| 205 | {ID: "iscsi_daemons_down_num", Name: "down"}, |
| 206 | }, |
| 207 | } |
| 208 | ) |
| 209 | |
| 210 | var ( |
| 211 | clusterPhysCapacityUtilizationChart = collectorapi.Chart{ |
| 212 | ID: "cluster_physical_capacity_utilization", |
| 213 | Title: "Ceph Cluster Physical Capacity Utilization", |
| 214 | Fam: "capacity", |
| 215 | Units: "percent", |
| 216 | Ctx: "ceph.cluster_physical_capacity_utilization", |
| 217 | Type: collectorapi.Area, |
| 218 | Priority: prioClusterPhysCapacityUtilization, |
| 219 | Dims: collectorapi.Dims{ |
| 220 | {ID: "raw_capacity_utilization", Name: "utilization", Div: precision}, |
| 221 | }, |
| 222 | } |
| 223 | clusterPhysCapacityUsageChart = collectorapi.Chart{ |
| 224 | ID: "cluster_physical_capacity_usage", |
| 225 | Title: "Ceph Cluster Physical Capacity Usage", |
| 226 | Fam: "capacity", |
| 227 | Units: "bytes", |
| 228 | Ctx: "ceph.cluster_physical_capacity_usage", |
| 229 | Type: collectorapi.Stacked, |
| 230 | Priority: prioClusterPhysCapacityUsage, |
| 231 | Dims: collectorapi.Dims{ |
| 232 | {ID: "raw_capacity_avail_bytes", Name: "avail"}, |
| 233 | {ID: "raw_capacity_used_bytes", Name: "used"}, |
| 234 | }, |
| 235 | } |
| 236 | clusterObjectsCountChart = collectorapi.Chart{ |
| 237 | ID: "cluster_objects_count", |
| 238 | Title: "Ceph Cluster Objects", |
| 239 | Fam: "capacity", |
| 240 | Units: "objects", |
| 241 | Ctx: "ceph.cluster_objects_count", |
| 242 | Type: collectorapi.Line, |
| 243 | Priority: prioClusterObjectsCount, |
| 244 | Dims: collectorapi.Dims{ |
| 245 | {ID: "objects_num", Name: "objects"}, |
| 246 | }, |
| 247 | } |
| 248 | clusterObjectsByStatusPercentChart = collectorapi.Chart{ |
| 249 | ID: "cluster_objects_by_status", |
| 250 | Title: "Ceph Cluster Objects by Status", |
| 251 | Fam: "capacity", |
| 252 | Units: "percent", |
| 253 | Ctx: "ceph.cluster_objects_by_status_distribution", |
| 254 | Type: collectorapi.Stacked, |
| 255 | Priority: prioClusterObjectsByStatusPercent, |
| 256 | Dims: collectorapi.Dims{ |
| 257 | {ID: "objects_healthy_num", Name: "healthy", Algo: collectorapi.PercentOfAbsolute}, |
| 258 | {ID: "objects_misplaced_num", Name: "misplaced", Algo: collectorapi.PercentOfAbsolute}, |
| 259 | {ID: "objects_degraded_num", Name: "degraded", Algo: collectorapi.PercentOfAbsolute}, |
| 260 | {ID: "objects_unfound_num", Name: "unfound", Algo: collectorapi.PercentOfAbsolute}, |
| 261 | }, |
| 262 | } |
| 263 | clusterPoolsCountChart = collectorapi.Chart{ |
| 264 | ID: "cluster_pools_count", |
| 265 | Title: "Ceph Cluster Pools", |
| 266 | Fam: "capacity", |
| 267 | Units: "pools", |
| 268 | Ctx: "ceph.cluster_pools_count", |
| 269 | Type: collectorapi.Line, |
| 270 | Priority: prioClusterPoolsCount, |
| 271 | Dims: collectorapi.Dims{ |
| 272 | {ID: "pools_num", Name: "pools"}, |
| 273 | }, |
| 274 | } |
| 275 | clusterPGsCountChart = collectorapi.Chart{ |
| 276 | ID: "cluster_pgs_count", |
| 277 | Title: "Ceph Cluster Placement Groups", |
| 278 | Fam: "capacity", |
| 279 | Units: "pgs", |
| 280 | Ctx: "ceph.cluster_pgs_count", |
| 281 | Type: collectorapi.Line, |
| 282 | Priority: prioClusterPGsCount, |
| 283 | Dims: collectorapi.Dims{ |
| 284 | {ID: "pgs_num", Name: "pgs"}, |
| 285 | }, |
| 286 | } |
| 287 | clusterPGsByStatusCountChart = collectorapi.Chart{ |
| 288 | ID: "cluster_pgs_by_status_count", |
| 289 | Title: "Ceph Cluster Placement Groups by Status", |
| 290 | Fam: "capacity", |
| 291 | Units: "pgs", |
| 292 | Ctx: "ceph.cluster_pgs_by_status_count", |
| 293 | Type: collectorapi.Stacked, |
| 294 | Priority: prioClusterPGsByStatusCount, |
| 295 | Dims: collectorapi.Dims{ |
| 296 | {ID: "pg_status_category_clean", Name: "clean"}, |
| 297 | {ID: "pg_status_category_working", Name: "working"}, |
| 298 | {ID: "pg_status_category_warning", Name: "warning"}, |
| 299 | {ID: "pg_status_category_unknown", Name: "unknown"}, |
| 300 | }, |
| 301 | } |
| 302 | clusterPgsPerOsdCountChart = collectorapi.Chart{ |
| 303 | ID: "cluster_pgs_per_osd_count", |
| 304 | Title: "Ceph Cluster Placement Groups per OSD", |
| 305 | Fam: "capacity", |
| 306 | Units: "pgs", |
| 307 | Ctx: "ceph.cluster_pgs_per_osd_count", |
| 308 | Type: collectorapi.Line, |
| 309 | Priority: prioClusterPGsPerOsdCount, |
| 310 | Dims: collectorapi.Dims{ |
| 311 | {ID: "pgs_per_osd", Name: "per_osd"}, |
| 312 | }, |
| 313 | } |
| 314 | ) |
| 315 | |
| 316 | var ( |
| 317 | clusterClientIOChart = collectorapi.Chart{ |
| 318 | ID: "cluster_client_io", |
| 319 | Title: "Ceph Cluster Client IO", |
| 320 | Fam: "performance", |
| 321 | Units: "bytes/s", |
| 322 | Ctx: "ceph.cluster_client_io", |
| 323 | Type: collectorapi.Area, |
| 324 | Priority: prioClusterClientIO, |
| 325 | Dims: collectorapi.Dims{ |
| 326 | {ID: "client_perf_read_bytes_sec", Name: "read"}, |
| 327 | {ID: "client_perf_write_bytes_sec", Name: "written", Mul: -1}, |
| 328 | }, |
| 329 | } |
| 330 | clusterClientIOPSChart = collectorapi.Chart{ |
| 331 | ID: "cluster_client_iops", |
| 332 | Title: "Ceph Cluster Client IOPS", |
| 333 | Fam: "performance", |
| 334 | Units: "ops/s", |
| 335 | Ctx: "ceph.cluster_client_iops", |
| 336 | Type: collectorapi.Line, |
| 337 | Priority: prioClusterClientIOPS, |
| 338 | Dims: collectorapi.Dims{ |
| 339 | {ID: "client_perf_read_op_per_sec", Name: "read"}, |
| 340 | {ID: "client_perf_write_op_per_sec", Name: "write", Mul: -1}, |
| 341 | }, |
| 342 | } |
| 343 | clusterRecoveryThroughputChart = collectorapi.Chart{ |
| 344 | ID: "cluster_recovery_throughput", |
| 345 | Title: "Ceph Cluster Recovery Throughput", |
| 346 | Fam: "performance", |
| 347 | Units: "bytes/s", |
| 348 | Ctx: "ceph.cluster_recovery_throughput", |
| 349 | Type: collectorapi.Line, |
| 350 | Priority: prioClusterClientRecoveryThroughput, |
| 351 | Dims: collectorapi.Dims{ |
| 352 | {ID: "client_perf_recovering_bytes_per_sec", Name: "recovery"}, |
| 353 | }, |
| 354 | } |
| 355 | clusterScrubStatusChart = collectorapi.Chart{ |
| 356 | ID: "cluster_scrub_status", |
| 357 | Title: "Ceph Cluster Scrubbing Status", |
| 358 | Fam: "performance", |
| 359 | Units: "status", |
| 360 | Ctx: "ceph.cluster_scrub_status", |
| 361 | Type: collectorapi.Line, |
| 362 | Priority: prioClusterScrubStatus, |
| 363 | Dims: collectorapi.Dims{ |
| 364 | {ID: "scrub_status_disabled", Name: "disabled"}, |
| 365 | {ID: "scrub_status_active", Name: "active"}, |
| 366 | {ID: "scrub_status_inactive", Name: "inactive"}, |
| 367 | }, |
| 368 | } |
| 369 | ) |
| 370 | |
| 371 | var ( |
| 372 | osdStatusChartTmpl = collectorapi.Chart{ |
| 373 | ID: "osd_%s_status", |
| 374 | Title: "Ceph OSD Status", |
| 375 | Fam: "osd", |
| 376 | Units: "status", |
| 377 | Ctx: "ceph.osd_status", |
| 378 | Type: collectorapi.Line, |
| 379 | Priority: prioOsdStatus, |
| 380 | Dims: collectorapi.Dims{ |
| 381 | {ID: "osd_%s_status_up", Name: "up"}, |
| 382 | {ID: "osd_%s_status_down", Name: "down"}, |
| 383 | {ID: "osd_%s_status_in", Name: "in"}, |
| 384 | {ID: "osd_%s_status_out", Name: "out"}, |
| 385 | }, |
| 386 | } |
| 387 | osdSpaceUsageChartTmpl = collectorapi.Chart{ |
| 388 | ID: "osd_%s_space_usage", |
| 389 | Title: "Ceph OSD Space Usage", |
| 390 | Fam: "osd", |
| 391 | Units: "bytes", |
| 392 | Ctx: "ceph.osd_space_usage", |
| 393 | Type: collectorapi.Stacked, |
| 394 | Priority: prioOsdSpaceUsage, |
| 395 | Dims: collectorapi.Dims{ |
| 396 | {ID: "osd_%s_space_avail_bytes", Name: "avail"}, |
| 397 | {ID: "osd_%s_space_used_bytes", Name: "used"}, |
| 398 | }, |
| 399 | } |
| 400 | osdIOChartTmpl = collectorapi.Chart{ |
| 401 | ID: "osd_%s_io", |
| 402 | Title: "Ceph OSD IO", |
| 403 | Fam: "osd", |
| 404 | Units: "bytes/s", |
| 405 | Ctx: "ceph.osd_io", |
| 406 | Type: collectorapi.Area, |
| 407 | Priority: prioOsdIO, |
| 408 | Dims: collectorapi.Dims{ |
| 409 | {ID: "osd_%s_read_bytes", Name: "read", Algo: collectorapi.Incremental}, |
| 410 | {ID: "osd_%s_written_bytes", Name: "written", Algo: collectorapi.Incremental, Mul: -1}, |
| 411 | }, |
| 412 | } |
| 413 | osdIOPSChartTmpl = collectorapi.Chart{ |
| 414 | ID: "osd_%s_iops", |
| 415 | Title: "Ceph OSD IOPS", |
| 416 | Fam: "osd", |
| 417 | Units: "ops/s", |
| 418 | Ctx: "ceph.osd_iops", |
| 419 | Type: collectorapi.Line, |
| 420 | Priority: prioOsdIOPS, |
| 421 | Dims: collectorapi.Dims{ |
| 422 | {ID: "osd_%s_read_ops", Name: "read", Algo: collectorapi.Incremental}, |
| 423 | {ID: "osd_%s_write_ops", Name: "write", Algo: collectorapi.Incremental}, |
| 424 | }, |
| 425 | } |
| 426 | osdLatencyChartTmpl = collectorapi.Chart{ |
| 427 | ID: "osd_%s_latency", |
| 428 | Title: "Ceph OSD Latency", |
| 429 | Fam: "osd", |
| 430 | Units: "milliseconds", |
| 431 | Ctx: "ceph.osd_latency", |
| 432 | Type: collectorapi.Line, |
| 433 | Priority: prioOsdLatency, |
| 434 | Dims: collectorapi.Dims{ |
| 435 | {ID: "osd_%s_commit_latency_ms", Name: "commit"}, |
| 436 | {ID: "osd_%s_apply_latency_ms", Name: "apply"}, |
| 437 | }, |
| 438 | } |
| 439 | ) |
| 440 | |
| 441 | var ( |
| 442 | poolSpaceUtilizationChartTmpl = collectorapi.Chart{ |
| 443 | ID: "pool_%s_space_utilization", |
| 444 | Title: "Ceph Pool Space Utilization", |
| 445 | Fam: "pool", |
| 446 | Units: "percent", |
| 447 | Ctx: "ceph.pool_space_utilization", |
| 448 | Type: collectorapi.Area, |
| 449 | Priority: prioPoolSpaceUtilization, |
| 450 | Dims: collectorapi.Dims{ |
| 451 | {ID: "pool_%s_space_utilization", Name: "utilization", Div: precision}, |
| 452 | }, |
| 453 | } |
| 454 | poolSpaceUsageChartTmpl = collectorapi.Chart{ |
| 455 | ID: "pool_%s_space_usage", |
| 456 | Title: "Ceph Pool Space Usage", |
| 457 | Fam: "pool", |
| 458 | Units: "bytes", |
| 459 | Ctx: "ceph.pool_space_usage", |
| 460 | Type: collectorapi.Stacked, |
| 461 | Priority: prioPoolSpaceUsage, |
| 462 | Dims: collectorapi.Dims{ |
| 463 | {ID: "pool_%s_space_avail_bytes", Name: "avail"}, |
| 464 | {ID: "pool_%s_space_used_bytes", Name: "used"}, |
| 465 | }, |
| 466 | } |
| 467 | poolObjectsCountChartTmpl = collectorapi.Chart{ |
| 468 | ID: "pool_%s_objects_count", |
| 469 | Title: "Ceph Pool Objects", |
| 470 | Fam: "pool", |
| 471 | Units: "objects", |
| 472 | Ctx: "ceph.pool_objects_count", |
| 473 | Type: collectorapi.Line, |
| 474 | Priority: prioPoolObjectsCount, |
| 475 | Dims: collectorapi.Dims{ |
| 476 | {ID: "pool_%s_objects", Name: "objects"}, |
| 477 | }, |
| 478 | } |
| 479 | poolIOChartTmpl = collectorapi.Chart{ |
| 480 | ID: "pool_%s_io", |
| 481 | Title: "Ceph Pool IO", |
| 482 | Fam: "pool", |
| 483 | Units: "bytes/s", |
| 484 | Ctx: "ceph.pool_io", |
| 485 | Type: collectorapi.Area, |
| 486 | Priority: prioPoolIO, |
| 487 | Dims: collectorapi.Dims{ |
| 488 | {ID: "pool_%s_read_bytes", Name: "read", Algo: collectorapi.Incremental}, |
| 489 | {ID: "pool_%s_written_bytes", Name: "written", Algo: collectorapi.Incremental, Mul: -1}, |
| 490 | }, |
| 491 | } |
| 492 | poolIOPSChartTmpl = collectorapi.Chart{ |
| 493 | ID: "pool_%s_iops", |
| 494 | Title: "Ceph Pool IOPS", |
| 495 | Fam: "pool", |
| 496 | Units: "ops/s", |
| 497 | Ctx: "ceph.pool_iops", |
| 498 | Type: collectorapi.Line, |
| 499 | Priority: prioPoolIOPS, |
| 500 | Dims: collectorapi.Dims{ |
| 501 | {ID: "pool_%s_read_ops", Name: "read", Algo: collectorapi.Incremental}, |
| 502 | {ID: "pool_%s_write_ops", Name: "write", Algo: collectorapi.Incremental, Mul: -1}, |
| 503 | }, |
| 504 | } |
| 505 | ) |
| 506 | |
| 507 | func (c *Collector) addClusterCharts() { |
| 508 | charts := clusterCharts.Copy() |
| 509 | |
| 510 | for _, chart := range *charts { |
| 511 | chart.Labels = []collectorapi.Label{ |
| 512 | {Key: "fsid", Value: c.fsid}, |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | if err := c.Charts().Add(*charts...); err != nil { |
| 517 | c.Warning(err) |
| 518 | } |
| 519 | } |
| 520 | |
| 521 | func (c *Collector) addOsdCharts(osdUuid, devClass, osdName string) { |
| 522 | charts := osdChartsTmpl.Copy() |
| 523 | |
| 524 | for _, chart := range *charts { |
| 525 | chart.ID = fmt.Sprintf(chart.ID, osdUuid) |
| 526 | chart.ID = cleanChartID(chart.ID) |
| 527 | chart.Labels = []collectorapi.Label{ |
| 528 | {Key: "fsid", Value: c.fsid}, |
| 529 | {Key: "osd_uuid", Value: osdUuid}, |
| 530 | {Key: "osd_name", Value: osdName}, |
| 531 | {Key: "device_class", Value: devClass}, |
| 532 | } |
| 533 | for _, dim := range chart.Dims { |
| 534 | dim.ID = fmt.Sprintf(dim.ID, osdUuid) |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | if err := c.Charts().Add(*charts...); err != nil { |
| 539 | c.Warning(err) |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | func (c *Collector) addPoolCharts(poolName string) { |
| 544 | charts := poolChartsTmpl.Copy() |
| 545 | |
| 546 | for _, chart := range *charts { |
| 547 | chart.ID = fmt.Sprintf(chart.ID, poolName) |
| 548 | chart.ID = cleanChartID(chart.ID) |
| 549 | chart.Labels = []collectorapi.Label{ |
| 550 | {Key: "fsid", Value: c.fsid}, |
| 551 | {Key: "pool_name", Value: poolName}, |
| 552 | } |
| 553 | for _, dim := range chart.Dims { |
| 554 | dim.ID = fmt.Sprintf(dim.ID, poolName) |
| 555 | } |
| 556 | } |
| 557 | |
| 558 | if err := c.Charts().Add(*charts...); err != nil { |
| 559 | c.Warning(err) |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | func (c *Collector) removeCharts(prefix string) { |
| 564 | prefix = cleanChartID(prefix) |
| 565 | for _, chart := range *c.Charts() { |
| 566 | if strings.HasPrefix(chart.ID, prefix) { |
| 567 | chart.MarkRemove() |
| 568 | chart.MarkNotCreated() |
| 569 | } |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | func cleanChartID(id string) string { |
| 574 | r := strings.NewReplacer(".", "_", " ", "_") |
| 575 | return strings.ToLower(r.Replace(id)) |
| 576 | } |