fix(go.d/nvme): support v2.11 output format (#19505)
Ilya Mashchenko committed
Jan 28, 2025 at 12:18 UTC
766c0688a566d93f08f1ab5c128da07464044292
9 files changed
+380
-75
src/go/plugin/go.d/collector/nvme/collect.go
+6
-6
@@ -69,12 +69,12 @@ func (c *Collector) collectNVMeDevice(mx map[string]int64, devicePath string) er
69
mx["device_"+dev+"_thm_temp1_total_time"] = parseValue(stats.ThmTemp1TotalTime) // seconds
70
mx["device_"+dev+"_thm_temp2_total_time"] = parseValue(stats.ThmTemp2TotalTime) // seconds
71
72
- mx["device_"+dev+"_critical_warning_available_spare"] = metrix.Bool(parseValue(stats.CriticalWarning)&1 != 0)
73
- mx["device_"+dev+"_critical_warning_temp_threshold"] = metrix.Bool(parseValue(stats.CriticalWarning)&(1<<1) != 0)
74
- mx["device_"+dev+"_critical_warning_nvm_subsystem_reliability"] = metrix.Bool(parseValue(stats.CriticalWarning)&(1<<2) != 0)
75
- mx["device_"+dev+"_critical_warning_read_only"] = metrix.Bool(parseValue(stats.CriticalWarning)&(1<<3) != 0)
76
- mx["device_"+dev+"_critical_warning_volatile_mem_backup_failed"] = metrix.Bool(parseValue(stats.CriticalWarning)&(1<<4) != 0)
77
- mx["device_"+dev+"_critical_warning_persistent_memory_read_only"] = metrix.Bool(parseValue(stats.CriticalWarning)&(1<<5) != 0)
72
+ mx["device_"+dev+"_critical_warning_available_spare"] = metrix.Bool(parseValue(stats.CriticalWarningValue)&1 != 0)
73
+ mx["device_"+dev+"_critical_warning_temp_threshold"] = metrix.Bool(parseValue(stats.CriticalWarningValue)&(1<<1) != 0)
74
+ mx["device_"+dev+"_critical_warning_nvm_subsystem_reliability"] = metrix.Bool(parseValue(stats.CriticalWarningValue)&(1<<2) != 0)
75
+ mx["device_"+dev+"_critical_warning_read_only"] = metrix.Bool(parseValue(stats.CriticalWarningValue)&(1<<3) != 0)
76
+ mx["device_"+dev+"_critical_warning_volatile_mem_backup_failed"] = metrix.Bool(parseValue(stats.CriticalWarningValue)&(1<<4) != 0)
77
+ mx["device_"+dev+"_critical_warning_persistent_memory_read_only"] = metrix.Bool(parseValue(stats.CriticalWarningValue)&(1<<5) != 0)
78
79
return nil
80
}
src/go/plugin/go.d/collector/nvme/collector_test.go
+142
-46
@@ -22,21 +22,27 @@ var (
22
dataConfigJSON, _ = os.ReadFile("testdata/config.json")
23
dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
24
25
- dataNVMeListJSON, _ = os.ReadFile("testdata/nvme-list.json")
26
- dataNVMeListEmptyJSON, _ = os.ReadFile("testdata/nvme-list-empty.json")
27
- dataNVMeSmartLogJSON, _ = os.ReadFile("testdata/nvme-smart-log.json")
28
- dataNVMeSmartLogStringJSON, _ = os.ReadFile("testdata/nvme-smart-log-string.json")
29
- dataNVMeSmartLogFloatJSON, _ = os.ReadFile("testdata/nvme-smart-log-float.json")
25
+ dataNVMeListEmptyJson, _ = os.ReadFile("testdata/nvme-list-empty.json")
26
+
27
+ dataVer23NVMeListJson, _ = os.ReadFile("testdata/v2.3/nvme-list.json")
28
+ dataVer23NVMeSmartLogJson, _ = os.ReadFile("testdata/v2.3/nvme-smart-log.json")
29
+ dataVer23NVMeSmartLogStringJson, _ = os.ReadFile("testdata/v2.3/nvme-smart-log-string.json")
30
+ dataVer23NVMeSmartLogFloatJson, _ = os.ReadFile("testdata/v2.3/nvme-smart-log-float.json")
31
+
32
+ dataVer211NVMeListJson, _ = os.ReadFile("testdata/v2.11/nvme-list.json")
33
+ dataVer211NVMeSmartLogJson, _ = os.ReadFile("testdata/v2.11/nvme-smart-log.json")
34
)
35
36
func Test_testDataIsValid(t *testing.T) {
37
for name, data := range map[string][]byte{
38
"dataConfigJSON": dataConfigJSON,
39
"dataConfigYAML": dataConfigYAML,
36
- "dataNVMeListJSON": dataNVMeListJSON,
37
- "dataNVMeListEmptyJSON": dataNVMeListEmptyJSON,
38
- "dataNVMeSmartLogStringJSON": dataNVMeSmartLogStringJSON,
39
- "dataNVMeSmartLogFloatJSON": dataNVMeSmartLogFloatJSON,
40
+ "dataNVMeListEmptyJSON": dataNVMeListEmptyJson,
41
+ "dataNVMeListJSON": dataVer23NVMeListJson,
42
+ "dataNVMeSmartLogStringJSON": dataVer23NVMeSmartLogStringJson,
43
+ "dataNVMeSmartLogFloatJSON": dataVer23NVMeSmartLogFloatJson,
44
+ "dataVer211NVMeListJson": dataVer211NVMeListJson,
45
+ "dataVer211NVMeSmartLogJson": dataVer211NVMeSmartLogJson,
46
} {
47
require.NotNil(t, data, name)
48
}
@@ -85,7 +91,7 @@ func TestCollector_Check(t *testing.T) {
91
}{
92
"success if all calls successful": {
93
wantFail: false,
88
- prepare: prepareCaseOK,
94
+ prepare: prepareCaseVer23OK,
95
},
96
"fails if 'nvme list' returns an empty list": {
97
wantFail: true,
@@ -123,9 +129,97 @@ func TestCollector_Collect(t *testing.T) {
129
}
130
131
tests := map[string][]testCaseStep{
126
- "success if all calls successful": {
132
+ "v2.11: success if all calls successful": {
133
+ {
134
+ prepare: prepareCaseVer211OK,
135
+ check: func(t *testing.T, collr *Collector) {
136
+ mx := collr.Collect(context.Background())
137
+
138
+ expected := map[string]int64{
139
+ "device_nvme0n1_available_spare": 100,
140
+ "device_nvme0n1_controller_busy_time": 4172940,
141
+ "device_nvme0n1_critical_comp_time": 0,
142
+ "device_nvme0n1_critical_warning_available_spare": 0,
143
+ "device_nvme0n1_critical_warning_nvm_subsystem_reliability": 0,
144
+ "device_nvme0n1_critical_warning_persistent_memory_read_only": 0,
145
+ "device_nvme0n1_critical_warning_read_only": 0,
146
+ "device_nvme0n1_critical_warning_temp_threshold": 0,
147
+ "device_nvme0n1_critical_warning_volatile_mem_backup_failed": 0,
148
+ "device_nvme0n1_data_units_read": 91155062272000,
149
+ "device_nvme0n1_data_units_written": 987485941760000,
150
+ "device_nvme0n1_host_read_commands": 5808178366,
151
+ "device_nvme0n1_host_write_commands": 24273507789,
152
+ "device_nvme0n1_media_errors": 0,
153
+ "device_nvme0n1_num_err_log_entries": 212,
154
+ "device_nvme0n1_percentage_used": 30,
155
+ "device_nvme0n1_power_cycles": 99,
156
+ "device_nvme0n1_power_on_time": 87926400,
157
+ "device_nvme0n1_temperature": 50,
158
+ "device_nvme0n1_thm_temp1_total_time": 1474,
159
+ "device_nvme0n1_thm_temp1_trans_count": 3,
160
+ "device_nvme0n1_thm_temp2_total_time": 0,
161
+ "device_nvme0n1_thm_temp2_trans_count": 0,
162
+ "device_nvme0n1_unsafe_shutdowns": 49,
163
+ "device_nvme0n1_warning_temp_time": 0,
164
+ "device_nvme1n1_available_spare": 100,
165
+ "device_nvme1n1_controller_busy_time": 4172940,
166
+ "device_nvme1n1_critical_comp_time": 0,
167
+ "device_nvme1n1_critical_warning_available_spare": 0,
168
+ "device_nvme1n1_critical_warning_nvm_subsystem_reliability": 0,
169
+ "device_nvme1n1_critical_warning_persistent_memory_read_only": 0,
170
+ "device_nvme1n1_critical_warning_read_only": 0,
171
+ "device_nvme1n1_critical_warning_temp_threshold": 0,
172
+ "device_nvme1n1_critical_warning_volatile_mem_backup_failed": 0,
173
+ "device_nvme1n1_data_units_read": 91155062272000,
174
+ "device_nvme1n1_data_units_written": 987485941760000,
175
+ "device_nvme1n1_host_read_commands": 5808178366,
176
+ "device_nvme1n1_host_write_commands": 24273507789,
177
+ "device_nvme1n1_media_errors": 0,
178
+ "device_nvme1n1_num_err_log_entries": 212,
179
+ "device_nvme1n1_percentage_used": 30,
180
+ "device_nvme1n1_power_cycles": 99,
181
+ "device_nvme1n1_power_on_time": 87926400,
182
+ "device_nvme1n1_temperature": 50,
183
+ "device_nvme1n1_thm_temp1_total_time": 1474,
184
+ "device_nvme1n1_thm_temp1_trans_count": 3,
185
+ "device_nvme1n1_thm_temp2_total_time": 0,
186
+ "device_nvme1n1_thm_temp2_trans_count": 0,
187
+ "device_nvme1n1_unsafe_shutdowns": 49,
188
+ "device_nvme1n1_warning_temp_time": 0,
189
+ "device_nvme2n1_available_spare": 100,
190
+ "device_nvme2n1_controller_busy_time": 4172940,
191
+ "device_nvme2n1_critical_comp_time": 0,
192
+ "device_nvme2n1_critical_warning_available_spare": 0,
193
+ "device_nvme2n1_critical_warning_nvm_subsystem_reliability": 0,
194
+ "device_nvme2n1_critical_warning_persistent_memory_read_only": 0,
195
+ "device_nvme2n1_critical_warning_read_only": 0,
196
+ "device_nvme2n1_critical_warning_temp_threshold": 0,
197
+ "device_nvme2n1_critical_warning_volatile_mem_backup_failed": 0,
198
+ "device_nvme2n1_data_units_read": 91155062272000,
199
+ "device_nvme2n1_data_units_written": 987485941760000,
200
+ "device_nvme2n1_host_read_commands": 5808178366,
201
+ "device_nvme2n1_host_write_commands": 24273507789,
202
+ "device_nvme2n1_media_errors": 0,
203
+ "device_nvme2n1_num_err_log_entries": 212,
204
+ "device_nvme2n1_percentage_used": 30,
205
+ "device_nvme2n1_power_cycles": 99,
206
+ "device_nvme2n1_power_on_time": 87926400,
207
+ "device_nvme2n1_temperature": 50,
208
+ "device_nvme2n1_thm_temp1_total_time": 1474,
209
+ "device_nvme2n1_thm_temp1_trans_count": 3,
210
+ "device_nvme2n1_thm_temp2_total_time": 0,
211
+ "device_nvme2n1_thm_temp2_trans_count": 0,
212
+ "device_nvme2n1_unsafe_shutdowns": 49,
213
+ "device_nvme2n1_warning_temp_time": 0,
214
+ }
215
+
216
+ assert.Equal(t, expected, mx)
217
+ },
218
+ },
219
+ },
220
+ "v2.3: success if all calls successful": {
221
{
128
- prepare: prepareCaseOK,
222
+ prepare: prepareCaseVer23OK,
223
check: func(t *testing.T, collr *Collector) {
224
mx := collr.Collect(context.Background())
225
@@ -186,9 +280,9 @@ func TestCollector_Collect(t *testing.T) {
280
},
281
},
282
},
189
- "success if all calls successful with string values": {
283
+ "v2.3: success if all calls successful with string values": {
284
{
191
- prepare: prepareCaseStringValuesOK,
285
+ prepare: prepareCaseVer23StringValuesOK,
286
check: func(t *testing.T, collr *Collector) {
287
mx := collr.Collect(context.Background())
288
@@ -249,9 +343,9 @@ func TestCollector_Collect(t *testing.T) {
343
},
344
},
345
},
252
- "success if all calls successful with float values": {
346
+ "v2.3: success if all calls successful with float values": {
347
{
254
- prepare: prepareCaseFloatValuesOK,
348
+ prepare: prepareCaseVer23FloatValuesOK,
349
check: func(t *testing.T, collr *Collector) {
350
mx := collr.Collect(context.Background())
351
@@ -358,20 +452,38 @@ func TestCollector_Collect(t *testing.T) {
452
}
453
}
454
361
-func prepareCaseOK(collr *Collector) {
362
- collr.exec = &mockNVMeCLIExec{}
455
+func prepareCaseVer211OK(collr *Collector) {
456
+ collr.exec = &mockNVMeCLIExec{
457
+ dataList: dataVer211NVMeListJson,
458
+ dataSmartLog: dataVer211NVMeSmartLogJson,
459
+ }
460
+}
461
+
462
+func prepareCaseVer23OK(collr *Collector) {
463
+ collr.exec = &mockNVMeCLIExec{
464
+ dataList: dataVer23NVMeListJson,
465
+ dataSmartLog: dataVer23NVMeSmartLogJson,
466
+ }
467
}
468
365
-func prepareCaseStringValuesOK(collr *Collector) {
366
- collr.exec = &mockNVMeCLIExec{smartLogString: true}
469
+func prepareCaseVer23StringValuesOK(collr *Collector) {
470
+ collr.exec = &mockNVMeCLIExec{
471
+ dataList: dataVer23NVMeListJson,
472
+ dataSmartLog: dataVer23NVMeSmartLogStringJson,
473
+ }
474
}
475
369
-func prepareCaseFloatValuesOK(collr *Collector) {
370
- collr.exec = &mockNVMeCLIExec{smartLogFloat: true}
476
+func prepareCaseVer23FloatValuesOK(collr *Collector) {
477
+ collr.exec = &mockNVMeCLIExec{
478
+ dataList: dataVer23NVMeListJson,
479
+ dataSmartLog: dataVer23NVMeSmartLogFloatJson,
480
+ }
481
}
482
483
func prepareCaseEmptyList(collr *Collector) {
374
- collr.exec = &mockNVMeCLIExec{emptyList: true}
484
+ collr.exec = &mockNVMeCLIExec{
485
+ dataList: dataNVMeListEmptyJson,
486
+ }
487
}
488
489
func prepareCaseErrOnList(collr *Collector) {
@@ -383,11 +495,11 @@ func prepareCaseErrOnSmartLog(collr *Collector) {
495
}
496
497
type mockNVMeCLIExec struct {
386
- errOnList bool
387
- errOnSmartLog bool
388
- emptyList bool
389
- smartLogString bool
390
- smartLogFloat bool
498
+ errOnList bool
499
+ errOnSmartLog bool
500
+
501
+ dataList []byte
502
+ dataSmartLog []byte
503
}
504
505
func (m *mockNVMeCLIExec) list() (*nvmeDeviceList, error) {
@@ -395,13 +507,8 @@ func (m *mockNVMeCLIExec) list() (*nvmeDeviceList, error) {
507
return nil, errors.New("mock.list() error")
508
}
509
398
- data := dataNVMeListJSON
399
- if m.emptyList {
400
- data = dataNVMeListEmptyJSON
401
- }
402
-
510
var v nvmeDeviceList
404
- if err := json.Unmarshal(data, &v); err != nil {
511
+ if err := json.Unmarshal(m.dataList, &v); err != nil {
512
return nil, err
513
}
514
@@ -412,20 +519,9 @@ func (m *mockNVMeCLIExec) smartLog(_ string) (*nvmeDeviceSmartLog, error) {
519
if m.errOnSmartLog {
520
return nil, errors.New("mock.smartLog() error")
521
}
415
- if m.emptyList {
416
- return nil, errors.New("mock.smartLog() no devices error")
417
- }
418
-
419
- data := dataNVMeSmartLogJSON
420
- if m.smartLogString {
421
- data = dataNVMeSmartLogStringJSON
422
- }
423
- if m.smartLogFloat {
424
- data = dataNVMeSmartLogFloatJSON
425
- }
522
523
var v nvmeDeviceSmartLog
428
- if err := json.Unmarshal(data, &v); err != nil {
524
+ if err := json.Unmarshal(m.dataSmartLog, &v); err != nil {
525
return nil, err
526
}
527
src/go/plugin/go.d/collector/nvme/exec.go
+101
-21
@@ -9,6 +9,7 @@ import (
9
"context"
10
"encoding/json"
11
"os/exec"
12
+ "strconv"
13
"time"
14
)
15
@@ -21,30 +22,109 @@ type nvmeDeviceList struct {
22
}
23
}
24
25
+func (n *nvmeDeviceList) UnmarshalJSON(b []byte) error {
26
+ type plain nvmeDeviceList
27
+
28
+ if err := json.Unmarshal(b, (*plain)(n)); err != nil {
29
+ return err
30
+ }
31
+
32
+ for _, d := range n.Devices {
33
+ if d.DevicePath != "" {
34
+ return nil
35
+ }
36
+ n.Devices = n.Devices[:0]
37
+ break
38
+ }
39
+
40
+ var v211Format struct {
41
+ Devices []struct {
42
+ Subsystems []struct {
43
+ Controllers []struct {
44
+ SerialNumber string `json:"SerialNumber"`
45
+ ModelNumber string `json:"ModelNumber"`
46
+ Firmware string `json:"Firmware"`
47
+ Namespaces []struct {
48
+ NameSpace string `json:"NameSpace"`
49
+ } `json:"Namespaces"`
50
+ } `json:"Controllers"`
51
+ } `json:"Subsystems"`
52
+ } `json:"Devices"`
53
+ }
54
+
55
+ if err := json.Unmarshal(b, &v211Format); err != nil {
56
+ return err
57
+ }
58
+
59
+ for _, device := range v211Format.Devices {
60
+ for _, subsystem := range device.Subsystems {
61
+ for _, controller := range subsystem.Controllers {
62
+ for _, namespace := range controller.Namespaces {
63
+ n.Devices = append(n.Devices, struct {
64
+ DevicePath string `json:"DevicePath"`
65
+ Firmware string `json:"Firmware"`
66
+ ModelNumber string `json:"ModelNumber"`
67
+ SerialNumber string `json:"SerialNumber"`
68
+ }{
69
+ DevicePath: namespace.NameSpace,
70
+ Firmware: controller.Firmware,
71
+ ModelNumber: controller.ModelNumber,
72
+ SerialNumber: controller.SerialNumber,
73
+ })
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ return nil
80
+}
81
+
82
// See "Health Information Log Page" in the Current Specification Version
83
// https://nvmexpress.org/developers/nvme-specification/
84
type nvmeDeviceSmartLog struct {
27
- CriticalWarning nvmeNumber `json:"critical_warning"`
28
- Temperature nvmeNumber `json:"temperature"`
29
- AvailSpare nvmeNumber `json:"avail_spare"`
30
- SpareThresh nvmeNumber `json:"spare_thresh"`
31
- PercentUsed nvmeNumber `json:"percent_used"`
32
- DataUnitsRead nvmeNumber `json:"data_units_read"`
33
- DataUnitsWritten nvmeNumber `json:"data_units_written"`
34
- HostReadCommands nvmeNumber `json:"host_read_commands"`
35
- HostWriteCommands nvmeNumber `json:"host_write_commands"`
36
- ControllerBusyTime nvmeNumber `json:"controller_busy_time"`
37
- PowerCycles nvmeNumber `json:"power_cycles"`
38
- PowerOnHours nvmeNumber `json:"power_on_hours"`
39
- UnsafeShutdowns nvmeNumber `json:"unsafe_shutdowns"`
40
- MediaErrors nvmeNumber `json:"media_errors"`
41
- NumErrLogEntries nvmeNumber `json:"num_err_log_entries"`
42
- WarningTempTime nvmeNumber `json:"warning_temp_time"`
43
- CriticalCompTime nvmeNumber `json:"critical_comp_time"`
44
- ThmTemp1TransCount nvmeNumber `json:"thm_temp1_trans_count"`
45
- ThmTemp2TransCount nvmeNumber `json:"thm_temp2_trans_count"`
46
- ThmTemp1TotalTime nvmeNumber `json:"thm_temp1_total_time"`
47
- ThmTemp2TotalTime nvmeNumber `json:"thm_temp2_total_time"`
85
+ CriticalWarningValue nvmeNumber
86
+ CriticalWarning json.RawMessage `json:"critical_warning"`
87
+ Temperature nvmeNumber `json:"temperature"`
88
+ AvailSpare nvmeNumber `json:"avail_spare"`
89
+ SpareThresh nvmeNumber `json:"spare_thresh"`
90
+ PercentUsed nvmeNumber `json:"percent_used"`
91
+ DataUnitsRead nvmeNumber `json:"data_units_read"`
92
+ DataUnitsWritten nvmeNumber `json:"data_units_written"`
93
+ HostReadCommands nvmeNumber `json:"host_read_commands"`
94
+ HostWriteCommands nvmeNumber `json:"host_write_commands"`
95
+ ControllerBusyTime nvmeNumber `json:"controller_busy_time"`
96
+ PowerCycles nvmeNumber `json:"power_cycles"`
97
+ PowerOnHours nvmeNumber `json:"power_on_hours"`
98
+ UnsafeShutdowns nvmeNumber `json:"unsafe_shutdowns"`
99
+ MediaErrors nvmeNumber `json:"media_errors"`
100
+ NumErrLogEntries nvmeNumber `json:"num_err_log_entries"`
101
+ WarningTempTime nvmeNumber `json:"warning_temp_time"`
102
+ CriticalCompTime nvmeNumber `json:"critical_comp_time"`
103
+ ThmTemp1TransCount nvmeNumber `json:"thm_temp1_trans_count"`
104
+ ThmTemp2TransCount nvmeNumber `json:"thm_temp2_trans_count"`
105
+ ThmTemp1TotalTime nvmeNumber `json:"thm_temp1_total_time"`
106
+ ThmTemp2TotalTime nvmeNumber `json:"thm_temp2_total_time"`
107
+}
108
+
109
+func (n *nvmeDeviceSmartLog) UnmarshalJSON(b []byte) error {
110
+ type plain nvmeDeviceSmartLog
111
+
112
+ if err := json.Unmarshal(b, (*plain)(n)); err != nil {
113
+ return err
114
+ }
115
+
116
+ if n.CriticalWarning != nil {
117
+ var v211Format struct {
118
+ Value int `json:"value"`
119
+ }
120
+ if err := json.Unmarshal(n.CriticalWarning, &v211Format); err == nil {
121
+ n.CriticalWarningValue = nvmeNumber(strconv.Itoa(v211Format.Value))
122
+ } else {
123
+ n.CriticalWarningValue = nvmeNumber(n.CriticalWarning)
124
+ }
125
+ }
126
+
127
+ return nil
128
}
129
130
// nvme-cli 2.1.1 exposes some values as strings
src/go/plugin/go.d/collector/nvme/testdata/v2.11/nvme-list.json
new
+97
@@ -0,0 +1,97 @@
1
+{
2
+ "Devices": [
3
+ {
4
+ "HostNQN": "nqn.2014-08.org.nvmexpress:uuid:e9184000-7983-11ec-8000-d85ed316925c",
5
+ "HostID": "e9184000-7983-11ec-8000-d85ed316925c",
6
+ "Subsystems": [
7
+ {
8
+ "Subsystem": "nvme-subsys0",
9
+ "SubsystemNQN": "nqn.2014.08.org.nvmexpress:1bb11bb1XXX02YYY Seagate FireCuda 530 ZP4000GM30023",
10
+ "Controllers": [
11
+ {
12
+ "Controller": "nvme0",
13
+ "Cntlid": "1",
14
+ "SerialNumber": "XXX02YYY",
15
+ "ModelNumber": "Seagate FireCuda 530 ZP4000GM30023",
16
+ "Firmware": "SU6SM005",
17
+ "Transport": "pcie",
18
+ "Address": "0000:01:00.0",
19
+ "Slot": "",
20
+ "Namespaces": [
21
+ {
22
+ "NameSpace": "nvme0n1",
23
+ "Generic": "ng0n1",
24
+ "NSID": 1,
25
+ "UsedBytes": 4000787030016,
26
+ "MaximumLBA": 7814037168,
27
+ "PhysicalSize": 4000787030016,
28
+ "SectorSize": 512
29
+ }
30
+ ],
31
+ "Paths": []
32
+ }
33
+ ],
34
+ "Namespaces": []
35
+ },
36
+ {
37
+ "Subsystem": "nvme-subsys1",
38
+ "SubsystemNQN": "nqn.2014.08.org.nvmexpress:1bb11bb1XXX00YYY Seagate FireCuda 530 ZP4000GM30023",
39
+ "Controllers": [
40
+ {
41
+ "Controller": "nvme1",
42
+ "Cntlid": "1",
43
+ "SerialNumber": "XXX00YYY",
44
+ "ModelNumber": "Seagate FireCuda 530 ZP4000GM30023",
45
+ "Firmware": "SU6SM001",
46
+ "Transport": "pcie",
47
+ "Address": "0000:81:00.0",
48
+ "Slot": "",
49
+ "Namespaces": [
50
+ {
51
+ "NameSpace": "nvme1n1",
52
+ "Generic": "ng1n1",
53
+ "NSID": 1,
54
+ "UsedBytes": 4000787030016,
55
+ "MaximumLBA": 7814037168,
56
+ "PhysicalSize": 4000787030016,
57
+ "SectorSize": 512
58
+ }
59
+ ],
60
+ "Paths": []
61
+ }
62
+ ],
63
+ "Namespaces": []
64
+ },
65
+ {
66
+ "Subsystem": "nvme-subsys2",
67
+ "SubsystemNQN": "nqn.2014.08.org.nvmexpress:1bb11bb17VS00KNX Seagate FireCuda 530 ZP4000GM30023",
68
+ "Controllers": [
69
+ {
70
+ "Controller": "nvme2",
71
+ "Cntlid": "1",
72
+ "SerialNumber": "7VS00KNX",
73
+ "ModelNumber": "Seagate FireCuda 530 ZP4000GM30023",
74
+ "Firmware": "SU6SM001",
75
+ "Transport": "pcie",
76
+ "Address": "0000:61:00.0",
77
+ "Slot": "",
78
+ "Namespaces": [
79
+ {
80
+ "NameSpace": "nvme2n1",
81
+ "Generic": "ng2n1",
82
+ "NSID": 1,
83
+ "UsedBytes": 4000787030016,
84
+ "MaximumLBA": 7814037168,
85
+ "PhysicalSize": 4000787030016,
86
+ "SectorSize": 512
87
+ }
88
+ ],
89
+ "Paths": []
90
+ }
91
+ ],
92
+ "Namespaces": []
93
+ }
94
+ ]
95
+ }
96
+ ]
97
+}
src/go/plugin/go.d/collector/nvme/testdata/v2.11/nvme-smart-log.json
new
+32
@@ -0,0 +1,32 @@
1
+{
2
+ "critical_warning": {
3
+ "value": 0,
4
+ "available_spare": 0,
5
+ "temp_threshold": 0,
6
+ "reliability_degraded": 0,
7
+ "ro": 0,
8
+ "vmbu_failed": 0,
9
+ "pmr_ro": 0
10
+ },
11
+ "temperature": 324,
12
+ "avail_spare": 100,
13
+ "spare_thresh": 5,
14
+ "percent_used": 30,
15
+ "endurance_grp_critical_warning_summary": 0,
16
+ "data_units_read": 178037231,
17
+ "data_units_written": 1928683480,
18
+ "host_read_commands": 5808178366,
19
+ "host_write_commands": 24273507789,
20
+ "controller_busy_time": 69549,
21
+ "power_cycles": 99,
22
+ "power_on_hours": 24424,
23
+ "unsafe_shutdowns": 49,
24
+ "media_errors": 0,
25
+ "num_err_log_entries": 212,
26
+ "warning_temp_time": 0,
27
+ "critical_comp_time": 0,
28
+ "thm_temp1_trans_count": 3,
29
+ "thm_temp2_trans_count": 0,
30
+ "thm_temp1_total_time": 1474,
31
+ "thm_temp2_total_time": 0
32
+}
src/go/plugin/go.d/collector/nvme/testdata/v2.3/nvme-list.json
renamed
+2
-2
@@ -7,7 +7,7 @@
7
"Index": 0,
8
"ModelNumber": "Seagate FireCuda 530 ZP4000GM30023",
9
"ProductName": "Non-Volatile memory controller: Seagate Technology PLC Device 0x5018",
10
- "SerialNumber": "7VS00KNX",
10
+ "SerialNumber": "XXX00YYY",
11
"UsedBytes": 4000787030016,
12
"MaximumLBA": 7814037168,
13
"PhysicalSize": 4000787030016,
@@ -20,7 +20,7 @@
20
"Index": 1,
21
"ModelNumber": "Seagate FireCuda 530 ZP4000GM30023",
22
"ProductName": "Non-Volatile memory controller: Seagate Technology PLC Device 0x5018",
23
- "SerialNumber": "7VS00J76",
23
+ "SerialNumber": "XXX01YYY",
24
"UsedBytes": 4000787030016,
25
"MaximumLBA": 7814037168,
26
"PhysicalSize": 4000787030016,