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