@@ -26,11 +26,12 @@ func scanDevices() ([]string, error) {
26
26
return devices , nil
27
27
}
28
28
29
+ // parseSmartctlOutput parses the output from smartctl command
29
30
func parseSmartctlOutput (output string ) * SmartMetric {
30
31
startMarker := "=== START OF SMART DATA SECTION ==="
31
32
startIdx := strings .Index (output , startMarker )
32
33
if startIdx == - 1 {
33
- return & SmartMetric {Data : make ( map [ string ] string ) }
34
+ return & SmartMetric {Data : SmartData {}, Errors : [] CustomErr {} }
34
35
}
35
36
36
37
section := output [startIdx :]
@@ -39,7 +40,8 @@ func parseSmartctlOutput(output string) *SmartMetric {
39
40
section = section [:endIdx ]
40
41
}
41
42
42
- data := make (map [string ]string )
43
+ data := SmartData {}
44
+ var errors []CustomErr
43
45
lines := strings .Split (section , "\n " )
44
46
45
47
for _ , line := range lines {
@@ -59,12 +61,56 @@ func parseSmartctlOutput(output string) *SmartMetric {
59
61
// Clean up value: remove extra spaces and brackets
60
62
value = regexp .MustCompile (`\s+` ).ReplaceAllString (value , " " )
61
63
value = strings .Trim (value , "[]" )
62
-
63
- data [key ] = value
64
+
65
+ switch strings .ToLower (key ) {
66
+ case "available spare" :
67
+ data .AvailableSpare = value
68
+ case "available spare threshold" :
69
+ data .AvailableSpareThreshold = value
70
+ case "controller busy time" :
71
+ data .ControllerBusyTime = value
72
+ case "critical warning" :
73
+ data .CriticalWarning = value
74
+ case "data units read" :
75
+ data .DataUnitsRead = value
76
+ case "data units written" :
77
+ data .DataUnitsWritten = value
78
+ case "error information log entries" :
79
+ data .ErrorInformationLogEntries = value
80
+ case "host read commands" :
81
+ data .HostReadCommands = value
82
+ case "host write commands" :
83
+ data .HostWriteCommands = value
84
+ case "media and data integrity errors" :
85
+ data .MediaAndDataIntegrityErrors = value
86
+ case "percentage used" :
87
+ data .PercentageUsed = value
88
+ case "power cycles" :
89
+ data .PowerCycles = value
90
+ case "power on hours" :
91
+ data .PowerOnHours = value
92
+ case "read 1 entries from error information log failed" :
93
+ data .Read1EntriesFromErrorLogFailed = value
94
+ case "smart overall-health self-assessment test result" :
95
+ data .SmartOverallHealthResult = value
96
+ case "temperature" :
97
+ data .Temperature = value
98
+ case "unsafe shutdowns" :
99
+ data .UnsafeShutdowns = value
100
+ }
101
+
102
+ // If the key contains "error" or "failed", add it to the errors
103
+ if strings .Contains (key , "failed" ) || strings .Contains (key , "error" ) {
104
+ errors = append (errors , CustomErr {
105
+ Metric : []string {key },
106
+ Error : fmt .Sprintf ("Unable to retrieve the '%s'" , key ),
107
+ })
108
+ }
64
109
}
65
110
66
111
return & SmartMetric {
67
112
Data : data ,
113
+ Errors : errors ,
68
114
}
69
115
}
70
116
@@ -83,25 +129,26 @@ func getMetrics(device string) (*SmartMetric, error) {
83
129
return parseSmartctlOutput (string (out )), nil
84
130
}
85
131
86
- func GetSmartMetrics () (MetricsSlice , []CustomErr ) {
132
+ // GetSmartMetrics retrieves the SMART metrics from all available devices.
133
+ func GetSmartMetrics () (SmartMetric , []CustomErr ) {
87
134
var smartCtlrErrs []CustomErr
88
135
devices , err := scanDevices ()
89
136
if err != nil {
90
- smartCtlrErrs = append (smartCtlrErrs ,CustomErr {
91
- Metric : []string {"smart" },
92
- Error : err .Error (),
93
- })
137
+ smartCtlrErrs = append (smartCtlrErrs , CustomErr {
138
+ Metric : []string {"smart" },
139
+ Error : err .Error (),
140
+ })
94
141
}
95
142
96
- var metrics MetricsSlice // Use MetricsSlice instead of []* SmartMetric
143
+ var metrics SmartMetric
97
144
for _ , device := range devices {
98
145
metric , err := getMetrics (device )
99
146
if err != nil {
100
147
log .Printf ("Skipping %s: %v" , device , err )
101
148
continue
102
149
}
103
- metrics = append (metrics , metric )
150
+
151
+ metrics = * metric
104
152
}
105
-
106
153
return metrics , smartCtlrErrs
107
- }
154
+ }
0 commit comments