| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package powervault |
| 4 | |
| 5 | import "github.com/netdata/netdata/go/plugins/pkg/metrix" |
| 6 | |
| 7 | type collectorMetrics struct { |
| 8 | controller controllerGauges |
| 9 | volume volumeGauges |
| 10 | port portGauges |
| 11 | phy phyGauges |
| 12 | pool poolGauges |
| 13 | drive driveGauges |
| 14 | sensor sensorGauges |
| 15 | hardware hardwareGauges |
| 16 | system systemGauges |
| 17 | } |
| 18 | |
| 19 | // Controller performance: mix of gauges (instant) and counters (cumulative). |
| 20 | type controllerGauges struct { |
| 21 | iops metrix.SnapshotGaugeVec |
| 22 | throughput metrix.SnapshotGaugeVec |
| 23 | cpuLoad metrix.SnapshotGaugeVec |
| 24 | writeCacheUsed metrix.SnapshotGaugeVec |
| 25 | forwardedCmds metrix.SnapshotGaugeVec |
| 26 | dataRead metrix.SnapshotGaugeVec |
| 27 | dataWritten metrix.SnapshotGaugeVec |
| 28 | readOps metrix.SnapshotGaugeVec |
| 29 | writeOps metrix.SnapshotGaugeVec |
| 30 | writeCacheHits metrix.SnapshotGaugeVec |
| 31 | writeCacheMisses metrix.SnapshotGaugeVec |
| 32 | readCacheHits metrix.SnapshotGaugeVec |
| 33 | readCacheMisses metrix.SnapshotGaugeVec |
| 34 | } |
| 35 | |
| 36 | // Volume performance: same pattern as controller. |
| 37 | type volumeGauges struct { |
| 38 | iops metrix.SnapshotGaugeVec |
| 39 | throughput metrix.SnapshotGaugeVec |
| 40 | writeCachePercent metrix.SnapshotGaugeVec |
| 41 | dataRead metrix.SnapshotGaugeVec |
| 42 | dataWritten metrix.SnapshotGaugeVec |
| 43 | readOps metrix.SnapshotGaugeVec |
| 44 | writeOps metrix.SnapshotGaugeVec |
| 45 | writeCacheHits metrix.SnapshotGaugeVec |
| 46 | writeCacheMisses metrix.SnapshotGaugeVec |
| 47 | readCacheHits metrix.SnapshotGaugeVec |
| 48 | readCacheMisses metrix.SnapshotGaugeVec |
| 49 | tierSSD metrix.SnapshotGaugeVec |
| 50 | tierSAS metrix.SnapshotGaugeVec |
| 51 | tierSATA metrix.SnapshotGaugeVec |
| 52 | } |
| 53 | |
| 54 | // Port I/O counters (cumulative). |
| 55 | type portGauges struct { |
| 56 | readOps metrix.SnapshotGaugeVec |
| 57 | writeOps metrix.SnapshotGaugeVec |
| 58 | dataRead metrix.SnapshotGaugeVec |
| 59 | dataWritten metrix.SnapshotGaugeVec |
| 60 | } |
| 61 | |
| 62 | // SAS PHY error counters. |
| 63 | type phyGauges struct { |
| 64 | disparityErrors metrix.SnapshotGaugeVec |
| 65 | lostDwords metrix.SnapshotGaugeVec |
| 66 | invalidDwords metrix.SnapshotGaugeVec |
| 67 | } |
| 68 | |
| 69 | // Pool capacity. |
| 70 | type poolGauges struct { |
| 71 | totalBytes metrix.SnapshotGaugeVec |
| 72 | availableBytes metrix.SnapshotGaugeVec |
| 73 | } |
| 74 | |
| 75 | // Per-drive metrics. |
| 76 | type driveGauges struct { |
| 77 | temperature metrix.SnapshotGaugeVec |
| 78 | powerOnHours metrix.SnapshotGaugeVec |
| 79 | ssdLifeLeft metrix.SnapshotGaugeVec |
| 80 | } |
| 81 | |
| 82 | // Per-sensor metrics by type. |
| 83 | type sensorGauges struct { |
| 84 | temperature metrix.SnapshotGaugeVec |
| 85 | voltage metrix.SnapshotGaugeVec |
| 86 | current metrix.SnapshotGaugeVec |
| 87 | chargeCapacity metrix.SnapshotGaugeVec |
| 88 | } |
| 89 | |
| 90 | // Hardware health counts (global). |
| 91 | type hardwareGauges struct { |
| 92 | controllerOK, controllerDegraded, controllerFault, controllerUnknown metrix.SnapshotGauge |
| 93 | driveOK, driveDegraded, driveFault, driveUnknown metrix.SnapshotGauge |
| 94 | fanOK, fanDegraded, fanFault, fanUnknown metrix.SnapshotGauge |
| 95 | psuOK, psuDegraded, psuFault, psuUnknown metrix.SnapshotGauge |
| 96 | fruOK, fruDegraded, fruFault, fruUnknown metrix.SnapshotGauge |
| 97 | portOK, portDegraded, portFault, portUnknown metrix.SnapshotGauge |
| 98 | } |
| 99 | |
| 100 | // System-level health. |
| 101 | type systemGauges struct { |
| 102 | health metrix.SnapshotGauge |
| 103 | } |
| 104 | |
| 105 | func newCollectorMetrics(store metrix.CollectorStore) *collectorMetrics { |
| 106 | meter := store.Write().SnapshotMeter("") |
| 107 | |
| 108 | ctrlVec := meter.Vec("controller") |
| 109 | volVec := meter.Vec("volume") |
| 110 | portVec := meter.Vec("port") |
| 111 | phyVec := meter.Vec("port") // PHY errors aggregated per port |
| 112 | poolVec := meter.Vec("pool") |
| 113 | driveVec := meter.Vec("drive") |
| 114 | sensorVec := meter.Vec("sensor") |
| 115 | |
| 116 | return &collectorMetrics{ |
| 117 | controller: controllerGauges{ |
| 118 | iops: ctrlVec.Gauge("controller_iops"), |
| 119 | throughput: ctrlVec.Gauge("controller_throughput"), |
| 120 | cpuLoad: ctrlVec.Gauge("controller_cpu_load"), |
| 121 | writeCacheUsed: ctrlVec.Gauge("controller_write_cache_used"), |
| 122 | forwardedCmds: ctrlVec.Gauge("controller_forwarded_cmds"), |
| 123 | dataRead: ctrlVec.Gauge("controller_data_read"), |
| 124 | dataWritten: ctrlVec.Gauge("controller_data_written"), |
| 125 | readOps: ctrlVec.Gauge("controller_read_ops"), |
| 126 | writeOps: ctrlVec.Gauge("controller_write_ops"), |
| 127 | writeCacheHits: ctrlVec.Gauge("controller_write_cache_hits"), |
| 128 | writeCacheMisses: ctrlVec.Gauge("controller_write_cache_misses"), |
| 129 | readCacheHits: ctrlVec.Gauge("controller_read_cache_hits"), |
| 130 | readCacheMisses: ctrlVec.Gauge("controller_read_cache_misses"), |
| 131 | }, |
| 132 | volume: volumeGauges{ |
| 133 | iops: volVec.Gauge("volume_iops"), |
| 134 | throughput: volVec.Gauge("volume_throughput"), |
| 135 | writeCachePercent: volVec.Gauge("volume_write_cache_percent"), |
| 136 | dataRead: volVec.Gauge("volume_data_read"), |
| 137 | dataWritten: volVec.Gauge("volume_data_written"), |
| 138 | readOps: volVec.Gauge("volume_read_ops"), |
| 139 | writeOps: volVec.Gauge("volume_write_ops"), |
| 140 | writeCacheHits: volVec.Gauge("volume_write_cache_hits"), |
| 141 | writeCacheMisses: volVec.Gauge("volume_write_cache_misses"), |
| 142 | readCacheHits: volVec.Gauge("volume_read_cache_hits"), |
| 143 | readCacheMisses: volVec.Gauge("volume_read_cache_misses"), |
| 144 | tierSSD: volVec.Gauge("volume_tier_ssd"), |
| 145 | tierSAS: volVec.Gauge("volume_tier_sas"), |
| 146 | tierSATA: volVec.Gauge("volume_tier_sata"), |
| 147 | }, |
| 148 | port: portGauges{ |
| 149 | readOps: portVec.Gauge("port_read_ops"), |
| 150 | writeOps: portVec.Gauge("port_write_ops"), |
| 151 | dataRead: portVec.Gauge("port_data_read"), |
| 152 | dataWritten: portVec.Gauge("port_data_written"), |
| 153 | }, |
| 154 | phy: phyGauges{ |
| 155 | disparityErrors: phyVec.Gauge("phy_disparity_errors"), |
| 156 | lostDwords: phyVec.Gauge("phy_lost_dwords"), |
| 157 | invalidDwords: phyVec.Gauge("phy_invalid_dwords"), |
| 158 | }, |
| 159 | pool: poolGauges{ |
| 160 | totalBytes: poolVec.Gauge("pool_total_bytes"), |
| 161 | availableBytes: poolVec.Gauge("pool_available_bytes"), |
| 162 | }, |
| 163 | drive: driveGauges{ |
| 164 | temperature: driveVec.Gauge("drive_temperature"), |
| 165 | powerOnHours: driveVec.Gauge("drive_power_on_hours"), |
| 166 | ssdLifeLeft: driveVec.Gauge("drive_ssd_life_left"), |
| 167 | }, |
| 168 | sensor: sensorGauges{ |
| 169 | temperature: sensorVec.Gauge("sensor_temperature"), |
| 170 | voltage: sensorVec.Gauge("sensor_voltage"), |
| 171 | current: sensorVec.Gauge("sensor_current"), |
| 172 | chargeCapacity: sensorVec.Gauge("sensor_charge_capacity"), |
| 173 | }, |
| 174 | hardware: hardwareGauges{ |
| 175 | controllerOK: meter.Gauge("hw_controller_ok"), |
| 176 | controllerDegraded: meter.Gauge("hw_controller_degraded"), |
| 177 | controllerFault: meter.Gauge("hw_controller_fault"), |
| 178 | controllerUnknown: meter.Gauge("hw_controller_unknown"), |
| 179 | driveOK: meter.Gauge("hw_drive_ok"), |
| 180 | driveDegraded: meter.Gauge("hw_drive_degraded"), |
| 181 | driveFault: meter.Gauge("hw_drive_fault"), |
| 182 | driveUnknown: meter.Gauge("hw_drive_unknown"), |
| 183 | fanOK: meter.Gauge("hw_fan_ok"), |
| 184 | fanDegraded: meter.Gauge("hw_fan_degraded"), |
| 185 | fanFault: meter.Gauge("hw_fan_fault"), |
| 186 | fanUnknown: meter.Gauge("hw_fan_unknown"), |
| 187 | psuOK: meter.Gauge("hw_psu_ok"), |
| 188 | psuDegraded: meter.Gauge("hw_psu_degraded"), |
| 189 | psuFault: meter.Gauge("hw_psu_fault"), |
| 190 | psuUnknown: meter.Gauge("hw_psu_unknown"), |
| 191 | fruOK: meter.Gauge("hw_fru_ok"), |
| 192 | fruDegraded: meter.Gauge("hw_fru_degraded"), |
| 193 | fruFault: meter.Gauge("hw_fru_fault"), |
| 194 | fruUnknown: meter.Gauge("hw_fru_unknown"), |
| 195 | portOK: meter.Gauge("hw_port_ok"), |
| 196 | portDegraded: meter.Gauge("hw_port_degraded"), |
| 197 | portFault: meter.Gauge("hw_port_fault"), |
| 198 | portUnknown: meter.Gauge("hw_port_unknown"), |
| 199 | }, |
| 200 | system: systemGauges{ |
| 201 | health: meter.Gauge("system_health"), |
| 202 | }, |
| 203 | } |
| 204 | } |