@cryptotaxi247 / netdata-1 / commits / eed3f36e8

feat(go.d/nvme): add model_number label (#18741)

Ilya Mashchenko committed Oct 10, 2024 at 11:42 UTC eed3f36e8b36887da8a0c22e528565ebe61356ea
4 files changed +53 -45
src/go/plugin/go.d/modules/nvme/charts.go
+7 -2
@@ -237,13 +237,16 @@ var (
237 }
238 )
239
240 -func (n *NVMe) addDeviceCharts(device string) {
240 +func (n *NVMe) addDeviceCharts(devicePath, model string) {
241 + device := extractDeviceFromPath(devicePath)
242 +
243 charts := deviceChartsTmpl.Copy()
244
245 for _, chart := range *charts {
246 chart.ID = fmt.Sprintf(chart.ID, device)
247 chart.Labels = []module.Label{
248 {Key: "device", Value: device},
249 + {Key: "model_number", Value: model},
250 }
251 for _, dim := range chart.Dims {
252 dim.ID = fmt.Sprintf(dim.ID, device)
@@ -255,7 +258,9 @@ func (n *NVMe) addDeviceCharts(device string) {
258 }
259 }
260
258 -func (n *NVMe) removeDeviceCharts(device string) {
261 +func (n *NVMe) removeDeviceCharts(devicePath string) {
262 + device := extractDeviceFromPath(devicePath)
263 +
264 px := fmt.Sprintf("device_%s", device)
265
266 for _, chart := range *n.Charts() {
src/go/plugin/go.d/modules/nvme/collect.go
+40 -39
@@ -43,59 +43,60 @@ func (n *NVMe) collectNVMeDevice(mx map[string]int64, devicePath string) error {
43 return fmt.Errorf("exec nvme smart-log for '%s': %v", devicePath, err)
44 }
45
46 - device := extractDeviceFromPath(devicePath)
47 -
48 - mx["device_"+device+"_temperature"] = int64(float64(parseValue(stats.Temperature)) - 273.15) // Kelvin => Celsius
49 - mx["device_"+device+"_percentage_used"] = parseValue(stats.PercentUsed)
50 - mx["device_"+device+"_available_spare"] = parseValue(stats.AvailSpare)
51 - mx["device_"+device+"_data_units_read"] = parseValue(stats.DataUnitsRead) * 1000 * 512 // units => bytes
52 - mx["device_"+device+"_data_units_written"] = parseValue(stats.DataUnitsWritten) * 1000 * 512 // units => bytes
53 - mx["device_"+device+"_host_read_commands"] = parseValue(stats.HostReadCommands)
54 - mx["device_"+device+"_host_write_commands"] = parseValue(stats.HostWriteCommands)
55 - mx["device_"+device+"_power_cycles"] = parseValue(stats.PowerCycles)
56 - mx["device_"+device+"_power_on_time"] = parseValue(stats.PowerOnHours) * 3600 // hours => seconds
57 - mx["device_"+device+"_unsafe_shutdowns"] = parseValue(stats.UnsafeShutdowns)
58 - mx["device_"+device+"_media_errors"] = parseValue(stats.MediaErrors)
59 - mx["device_"+device+"_num_err_log_entries"] = parseValue(stats.NumErrLogEntries)
60 - mx["device_"+device+"_controller_busy_time"] = parseValue(stats.ControllerBusyTime) * 60 // minutes => seconds
61 - mx["device_"+device+"_warning_temp_time"] = parseValue(stats.WarningTempTime) * 60 // minutes => seconds
62 - mx["device_"+device+"_critical_comp_time"] = parseValue(stats.CriticalCompTime) * 60 // minutes => seconds
63 - mx["device_"+device+"_thm_temp1_trans_count"] = parseValue(stats.ThmTemp1TransCount)
64 - mx["device_"+device+"_thm_temp2_trans_count"] = parseValue(stats.ThmTemp2TransCount)
65 - mx["device_"+device+"_thm_temp1_total_time"] = parseValue(stats.ThmTemp1TotalTime) // seconds
66 - mx["device_"+device+"_thm_temp2_total_time"] = parseValue(stats.ThmTemp2TotalTime) // seconds
67 -
68 - mx["device_"+device+"_critical_warning_available_spare"] = boolToInt(parseValue(stats.CriticalWarning)&1 != 0)
69 - mx["device_"+device+"_critical_warning_temp_threshold"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<1) != 0)
70 - mx["device_"+device+"_critical_warning_nvm_subsystem_reliability"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<2) != 0)
71 - mx["device_"+device+"_critical_warning_read_only"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<3) != 0)
72 - mx["device_"+device+"_critical_warning_volatile_mem_backup_failed"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<4) != 0)
73 - mx["device_"+device+"_critical_warning_persistent_memory_read_only"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<5) != 0)
46 + dev := extractDeviceFromPath(devicePath)
47 +
48 + mx["device_"+dev+"_temperature"] = int64(float64(parseValue(stats.Temperature)) - 273.15) // Kelvin => Celsius
49 + mx["device_"+dev+"_percentage_used"] = parseValue(stats.PercentUsed)
50 + mx["device_"+dev+"_available_spare"] = parseValue(stats.AvailSpare)
51 + mx["device_"+dev+"_data_units_read"] = parseValue(stats.DataUnitsRead) * 1000 * 512 // units => bytes
52 + mx["device_"+dev+"_data_units_written"] = parseValue(stats.DataUnitsWritten) * 1000 * 512 // units => bytes
53 + mx["device_"+dev+"_host_read_commands"] = parseValue(stats.HostReadCommands)
54 + mx["device_"+dev+"_host_write_commands"] = parseValue(stats.HostWriteCommands)
55 + mx["device_"+dev+"_power_cycles"] = parseValue(stats.PowerCycles)
56 + mx["device_"+dev+"_power_on_time"] = parseValue(stats.PowerOnHours) * 3600 // hours => seconds
57 + mx["device_"+dev+"_unsafe_shutdowns"] = parseValue(stats.UnsafeShutdowns)
58 + mx["device_"+dev+"_media_errors"] = parseValue(stats.MediaErrors)
59 + mx["device_"+dev+"_num_err_log_entries"] = parseValue(stats.NumErrLogEntries)
60 + mx["device_"+dev+"_controller_busy_time"] = parseValue(stats.ControllerBusyTime) * 60 // minutes => seconds
61 + mx["device_"+dev+"_warning_temp_time"] = parseValue(stats.WarningTempTime) * 60 // minutes => seconds
62 + mx["device_"+dev+"_critical_comp_time"] = parseValue(stats.CriticalCompTime) * 60 // minutes => seconds
63 + mx["device_"+dev+"_thm_temp1_trans_count"] = parseValue(stats.ThmTemp1TransCount)
64 + mx["device_"+dev+"_thm_temp2_trans_count"] = parseValue(stats.ThmTemp2TransCount)
65 + mx["device_"+dev+"_thm_temp1_total_time"] = parseValue(stats.ThmTemp1TotalTime) // seconds
66 + mx["device_"+dev+"_thm_temp2_total_time"] = parseValue(stats.ThmTemp2TotalTime) // seconds
67 +
68 + mx["device_"+dev+"_critical_warning_available_spare"] = boolToInt(parseValue(stats.CriticalWarning)&1 != 0)
69 + mx["device_"+dev+"_critical_warning_temp_threshold"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<1) != 0)
70 + mx["device_"+dev+"_critical_warning_nvm_subsystem_reliability"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<2) != 0)
71 + mx["device_"+dev+"_critical_warning_read_only"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<3) != 0)
72 + mx["device_"+dev+"_critical_warning_volatile_mem_backup_failed"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<4) != 0)
73 + mx["device_"+dev+"_critical_warning_persistent_memory_read_only"] = boolToInt(parseValue(stats.CriticalWarning)&(1<<5) != 0)
74
75 return nil
76 }
77
78 func (n *NVMe) listNVMeDevices() error {
79 - devices, err := n.exec.list()
79 + devList, err := n.exec.list()
80 if err != nil {
81 return fmt.Errorf("exec nvme list: %v", err)
82 }
83
84 + n.Debugf("found %d NVMe devices (%v)", len(devList.Devices), devList.Devices)
85 +
86 seen := make(map[string]bool)
85 - for _, v := range devices.Devices {
86 - device := extractDeviceFromPath(v.DevicePath)
87 - seen[device] = true
87
89 - if !n.devicePaths[v.DevicePath] {
90 - n.devicePaths[v.DevicePath] = true
91 - n.addDeviceCharts(device)
88 + for _, dev := range devList.Devices {
89 + path := dev.DevicePath
90 + seen[path] = true
91 + if !n.devicePaths[path] {
92 + n.devicePaths[path] = true
93 + n.addDeviceCharts(path, dev.ModelNumber)
94 }
95 }
96 for path := range n.devicePaths {
95 - device := extractDeviceFromPath(path)
96 - if !seen[device] {
97 - delete(n.devicePaths, device)
98 - n.removeDeviceCharts(device)
97 + if !seen[path] {
98 + delete(n.devicePaths, path)
99 + n.removeDeviceCharts(path)
100 }
101 }
102
src/go/plugin/go.d/modules/nvme/exec.go
+4 -4
@@ -12,10 +12,10 @@ import (
12
13 type nvmeDeviceList struct {
14 Devices []struct {
15 - DevicePath string `json:"DevicePath"`
16 - UsedBytes nvmeNumber `json:"UsedBytes"`
17 - PhysicalSize nvmeNumber `json:"PhysicalSize"`
18 - SectorSize nvmeNumber `json:"SectorSize"`
15 + DevicePath string `json:"DevicePath"`
16 + Firmware string `json:"Firmware"`
17 + ModelNumber string `json:"ModelNumber"`
18 + SerialNumber string `json:"SerialNumber"`
19 }
20 }
21
src/go/plugin/go.d/modules/nvme/metadata.yaml
+2
@@ -120,6 +120,8 @@ modules:
120 labels:
121 - name: device
122 description: NVMe device name
123 + - name: model_number
124 + description: NVMe device model
125 metrics:
126 - name: nvme.device_estimated_endurance_perc
127 description: Estimated endurance