Skip to content

Commit 526787f

Browse files
committed
FIX-51 second draft by making sure the data output is as expected.
1 parent 52ffd69 commit 526787f

File tree

4 files changed

+88
-19
lines changed

4 files changed

+88
-19
lines changed

cmd/capture/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func main() {
5050
apiV1.GET("/metrics/memory", handler.MetricsMemory)
5151
apiV1.GET("/metrics/disk", handler.MetricsDisk)
5252
apiV1.GET("/metrics/host", handler.MetricsHost)
53-
apiV1.GET("/metrics/smartmetrics", handler.SmartMetrics)
53+
apiV1.GET("/metrics/smart", handler.SmartMetrics)
5454

5555

5656
server := &http.Server{

internal/handler/metrics.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ func MetricsHost(c *gin.Context) {
4242
}
4343

4444
func SmartMetrics(c *gin.Context) {
45-
smartMetrics, smartErrs := metric.GetSmartMetrics() // Returns []*SmartMetric
46-
handleMetricResponse(c, smartMetrics, smartErrs)
47-
}
45+
smartMetrics, smartErrs := metric.GetSmartMetrics()
46+
handleMetricResponse(c,smartMetrics.Data, append(smartMetrics.Errors, smartErrs...))
47+
}

internal/metric/metric.go

+24-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,34 @@ type APIResponse struct {
1414
}
1515

1616
type SmartMetric struct {
17-
Data map[string]string `json:"data"`
18-
Errors []CustomErr `json:"errors"`
17+
Data SmartData `json:"data"` // The SMART data
18+
Errors []CustomErr `json:"errors"` // Any errors encountered
1919
}
2020

2121
func (s SmartMetric) isMetric() {}
2222

23+
type SmartData struct {
24+
AvailableSpare string `json:"available_spare"`
25+
AvailableSpareThreshold string `json:"available_spare_threshold"`
26+
ControllerBusyTime string `json:"controller_busy_time"`
27+
CriticalWarning string `json:"critical_warning"`
28+
DataUnitsRead string `json:"data_units_read"`
29+
DataUnitsWritten string `json:"data_units_written"`
30+
ErrorInformationLogEntries string `json:"error_information_log_entries"`
31+
HostReadCommands string `json:"host_read_commands"`
32+
HostWriteCommands string `json:"host_write_commands"`
33+
MediaAndDataIntegrityErrors string `json:"media_and_data_integrity_errors"`
34+
PercentageUsed string `json:"percentage_used"`
35+
PowerCycles string `json:"power_cycles"`
36+
PowerOnHours string `json:"power_on_hours"`
37+
Read1EntriesFromErrorLogFailed string `json:"read_1_entries_from_error_information_log_failed"`
38+
SmartOverallHealthResult string `json:"smart_overall-health_self-assessment_test_result"`
39+
Temperature string `json:"temperature"`
40+
UnsafeShutdowns string `json:"unsafe_shutdowns"`
41+
}
42+
43+
func (s SmartData) isMetric() {}
44+
2345
type AllMetrics struct {
2446
CPU CPUData `json:"cpu"`
2547
Memory MemoryData `json:"memory"`

internal/metric/smart_metrics.go

+60-13
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ func scanDevices() ([]string, error) {
2626
return devices, nil
2727
}
2828

29+
// parseSmartctlOutput parses the output from smartctl command
2930
func parseSmartctlOutput(output string) *SmartMetric {
3031
startMarker := "=== START OF SMART DATA SECTION ==="
3132
startIdx := strings.Index(output, startMarker)
3233
if startIdx == -1 {
33-
return &SmartMetric{Data: make(map[string]string)}
34+
return &SmartMetric{Data: SmartData{}, Errors: []CustomErr{}}
3435
}
3536

3637
section := output[startIdx:]
@@ -39,7 +40,8 @@ func parseSmartctlOutput(output string) *SmartMetric {
3940
section = section[:endIdx]
4041
}
4142

42-
data := make(map[string]string)
43+
data := SmartData{}
44+
var errors []CustomErr
4345
lines := strings.Split(section, "\n")
4446

4547
for _, line := range lines {
@@ -59,12 +61,56 @@ func parseSmartctlOutput(output string) *SmartMetric {
5961
// Clean up value: remove extra spaces and brackets
6062
value = regexp.MustCompile(`\s+`).ReplaceAllString(value, " ")
6163
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+
}
64109
}
65110

66111
return &SmartMetric{
67112
Data: data,
113+
Errors: errors,
68114
}
69115
}
70116

@@ -83,25 +129,26 @@ func getMetrics(device string) (*SmartMetric, error) {
83129
return parseSmartctlOutput(string(out)), nil
84130
}
85131

86-
func GetSmartMetrics() (MetricsSlice, []CustomErr) {
132+
// GetSmartMetrics retrieves the SMART metrics from all available devices.
133+
func GetSmartMetrics() (SmartMetric, []CustomErr) {
87134
var smartCtlrErrs []CustomErr
88135
devices, err := scanDevices()
89136
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+
})
94141
}
95142

96-
var metrics MetricsSlice // Use MetricsSlice instead of []*SmartMetric
143+
var metrics SmartMetric
97144
for _, device := range devices {
98145
metric, err := getMetrics(device)
99146
if err != nil {
100147
log.Printf("Skipping %s: %v", device, err)
101148
continue
102149
}
103-
metrics = append(metrics, metric)
150+
151+
metrics = *metric
104152
}
105-
106153
return metrics, smartCtlrErrs
107-
}
154+
}

0 commit comments

Comments
 (0)