mirror of
https://github.com/prometheus-community/smartctl_exporter.git
synced 2024-11-16 01:33:07 +01:00
extend self-test log processing
Signed-off-by: Aritas1 <mail@aritas.de>
This commit is contained in:
parent
75c76b363f
commit
9e14bc2ef2
3 changed files with 58 additions and 1 deletions
11
metrics.go
11
metrics.go
|
@ -242,6 +242,17 @@ var (
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
metricDeviceSelfTest = prometheus.NewDesc(
|
||||||
|
"smartctl_device_self_test_log_seconds",
|
||||||
|
"Device SMART self test log execution lifetime seconds",
|
||||||
|
[]string{
|
||||||
|
"device",
|
||||||
|
"self_test_log_type",
|
||||||
|
"self_test_passed",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
metricDeviceSelfTestLogCount = prometheus.NewDesc(
|
metricDeviceSelfTestLogCount = prometheus.NewDesc(
|
||||||
"smartctl_device_self_test_log_count",
|
"smartctl_device_self_test_log_count",
|
||||||
"Device SMART self test log count",
|
"Device SMART self test log count",
|
||||||
|
|
|
@ -64,7 +64,7 @@ func readFakeSMARTctl(logger log.Logger, device string) gjson.Result {
|
||||||
// Get json from smartctl and parse it
|
// Get json from smartctl and parse it
|
||||||
func readSMARTctl(logger log.Logger, device string) (gjson.Result, bool) {
|
func readSMARTctl(logger log.Logger, device string) (gjson.Result, bool) {
|
||||||
level.Debug(logger).Log("msg", "Collecting S.M.A.R.T. counters", "device", device)
|
level.Debug(logger).Log("msg", "Collecting S.M.A.R.T. counters", "device", device)
|
||||||
out, err := exec.Command(*smartctlPath, "--json", "--info", "--health", "--attributes", "--tolerance=verypermissive", "--nocheck=standby", "--format=brief", "--log=error", device).Output()
|
out, err := exec.Command(*smartctlPath, "--json", "--info", "--health", "--attributes", "--tolerance=verypermissive", "--nocheck=standby", "--format=brief", "--log=error", "--log=selftest", device).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
level.Warn(logger).Log("msg", "S.M.A.R.T. output reading", "err", err, "device", device)
|
level.Warn(logger).Log("msg", "S.M.A.R.T. output reading", "err", err, "device", device)
|
||||||
}
|
}
|
||||||
|
|
46
smartctl.go
46
smartctl.go
|
@ -15,6 +15,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
|
@ -69,6 +70,7 @@ func (smart *SMARTctl) Collect() {
|
||||||
smart.mineDeviceSCTStatus()
|
smart.mineDeviceSCTStatus()
|
||||||
smart.mineDeviceStatistics()
|
smart.mineDeviceStatistics()
|
||||||
smart.mineDeviceErrorLog()
|
smart.mineDeviceErrorLog()
|
||||||
|
smart.mineDeviceSelfTest()
|
||||||
smart.mineDeviceSelfTestLog()
|
smart.mineDeviceSelfTestLog()
|
||||||
smart.mineDeviceERC()
|
smart.mineDeviceERC()
|
||||||
smart.minePercentageUsed()
|
smart.minePercentageUsed()
|
||||||
|
@ -399,6 +401,50 @@ func (smart *SMARTctl) mineDeviceErrorLog() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (smart *SMARTctl) mineDeviceSelfTest() {
|
||||||
|
validTypes := map[int]string{
|
||||||
|
255: "vendor",
|
||||||
|
129: "short_captive",
|
||||||
|
2: "long",
|
||||||
|
1: "short",
|
||||||
|
}
|
||||||
|
|
||||||
|
// assume the table will always be in descending order
|
||||||
|
processedTypes := make(map[string]bool)
|
||||||
|
|
||||||
|
for _, logEntry := range smart.json.Get("ata_smart_self_test_log.standard.table").Array() {
|
||||||
|
testType := int(logEntry.Get("type.value").Int())
|
||||||
|
testTime := float64(logEntry.Get("lifetime_hours").Int())
|
||||||
|
testRunningIndicator := int(logEntry.Get("status.value").Int())
|
||||||
|
testStatus := strconv.FormatBool(logEntry.Get("status.passed").Bool())
|
||||||
|
|
||||||
|
// stick with seconds
|
||||||
|
testTime = testTime * 60 * 60
|
||||||
|
|
||||||
|
// skip running tests
|
||||||
|
if testRunningIndicator != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
logTestType, exists := validTypes[testType]
|
||||||
|
if !exists {
|
||||||
|
logTestType = "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
if !processedTypes[logTestType] {
|
||||||
|
smart.ch <- prometheus.MustNewConstMetric(
|
||||||
|
metricDeviceSelfTest,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
testTime,
|
||||||
|
smart.device.device,
|
||||||
|
logTestType,
|
||||||
|
testStatus,
|
||||||
|
)
|
||||||
|
processedTypes[logTestType] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (smart *SMARTctl) mineDeviceSelfTestLog() {
|
func (smart *SMARTctl) mineDeviceSelfTestLog() {
|
||||||
for logType, status := range smart.json.Get("ata_smart_self_test_log").Map() {
|
for logType, status := range smart.json.Get("ata_smart_self_test_log").Map() {
|
||||||
smart.ch <- prometheus.MustNewConstMetric(
|
smart.ch <- prometheus.MustNewConstMetric(
|
||||||
|
|
Loading…
Reference in a new issue