summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/modules/smartctl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-26 08:15:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-26 08:15:20 +0000
commit87d772a7d708fec12f48cd8adc0dedff6e1025da (patch)
tree1fee344c64cc3f43074a01981e21126c8482a522 /src/go/collectors/go.d.plugin/modules/smartctl
parentAdding upstream version 1.46.3. (diff)
downloadnetdata-87d772a7d708fec12f48cd8adc0dedff6e1025da.tar.xz
netdata-87d772a7d708fec12f48cd8adc0dedff6e1025da.zip
Adding upstream version 1.47.0.upstream/1.47.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/go/collectors/go.d.plugin/modules/smartctl')
l---------src/go/collectors/go.d.plugin/modules/smartctl/README.md1
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/charts.go299
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/collect.go189
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/config_schema.json99
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/exec.go82
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/init.go46
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/integrations/s.m.a.r.t..md181
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/metadata.yaml161
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/scan.go75
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/smart_device.go123
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/smartctl.go140
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/smartctl_test.go436
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.json8
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.yaml6
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/device-nvme0.json112
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/scan.json29
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-hdd-sda.json601
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-ssd-sdc.json652
-rw-r--r--src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/scan.json35
19 files changed, 0 insertions, 3275 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/README.md b/src/go/collectors/go.d.plugin/modules/smartctl/README.md
deleted file mode 120000
index 63aad6c85..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/README.md
+++ /dev/null
@@ -1 +0,0 @@
-integrations/s.m.a.r.t..md \ No newline at end of file
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/charts.go b/src/go/collectors/go.d.plugin/modules/smartctl/charts.go
deleted file mode 100644
index 2a5fea02b..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/charts.go
+++ /dev/null
@@ -1,299 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- "fmt"
- "strings"
-
- "github.com/netdata/netdata/go/go.d.plugin/agent/module"
-)
-
-const (
- prioDeviceSmartStatus = module.Priority + iota
- prioDeviceAtaSmartErrorLogCount
- prioDevicePowerOnTime
- prioDeviceTemperature
- prioDevicePowerCycleCount
-
- prioDeviceSmartAttributeDecoded
- prioDeviceSmartAttributeNormalized
-)
-
-var deviceChartsTmpl = module.Charts{
- devicePowerOnTimeChartTmpl.Copy(),
- deviceTemperatureChartTmpl.Copy(),
- devicePowerCycleCountChartTmpl.Copy(),
- deviceSmartStatusChartTmpl.Copy(),
- deviceAtaSmartErrorLogCountChartTmpl.Copy(),
-}
-
-var (
- deviceSmartStatusChartTmpl = module.Chart{
- ID: "device_%s_type_%s_smart_status",
- Title: "Device smart status",
- Units: "status",
- Fam: "smart status",
- Ctx: "smartctl.device_smart_status",
- Type: module.Line,
- Priority: prioDeviceSmartStatus,
- Dims: module.Dims{
- {ID: "device_%s_type_%s_smart_status_passed", Name: "passed"},
- {ID: "device_%s_type_%s_smart_status_failed", Name: "failed"},
- },
- }
- deviceAtaSmartErrorLogCountChartTmpl = module.Chart{
- ID: "device_%s_type_%s_ata_smart_error_log_count",
- Title: "Device ATA smart error log count",
- Units: "logs",
- Fam: "smart error log",
- Ctx: "smartctl.device_ata_smart_error_log_count",
- Type: module.Line,
- Priority: prioDeviceAtaSmartErrorLogCount,
- Dims: module.Dims{
- {ID: "device_%s_type_%s_ata_smart_error_log_summary_count", Name: "error_log"},
- },
- }
- devicePowerOnTimeChartTmpl = module.Chart{
- ID: "device_%s_type_%s_power_on_time",
- Title: "Device power on time",
- Units: "seconds",
- Fam: "power on time",
- Ctx: "smartctl.device_power_on_time",
- Type: module.Line,
- Priority: prioDevicePowerOnTime,
- Dims: module.Dims{
- {ID: "device_%s_type_%s_power_on_time", Name: "power_on_time"},
- },
- }
- deviceTemperatureChartTmpl = module.Chart{
- ID: "device_%s_type_%s_temperature",
- Title: "Device temperature",
- Units: "Celsius",
- Fam: "temperature",
- Ctx: "smartctl.device_temperature",
- Type: module.Line,
- Priority: prioDeviceTemperature,
- Dims: module.Dims{
- {ID: "device_%s_type_%s_temperature", Name: "temperature"},
- },
- }
- devicePowerCycleCountChartTmpl = module.Chart{
- ID: "device_%s_type_%s_power_cycle_count",
- Title: "Device power cycles",
- Units: "cycles",
- Fam: "power cycles",
- Ctx: "smartctl.device_power_cycles_count",
- Type: module.Line,
- Priority: prioDevicePowerCycleCount,
- Dims: module.Dims{
- {ID: "device_%s_type_%s_power_cycle_count", Name: "power"},
- },
- }
-)
-
-var (
- deviceSmartAttributeDecodedChartTmpl = module.Chart{
- ID: "device_%s_type_%s_smart_attr_%s",
- Title: "Device smart attribute %s",
- Units: "value",
- Fam: "attr %s",
- Ctx: "smartctl.device_smart_attr_%s",
- Type: module.Line,
- Priority: prioDeviceSmartAttributeDecoded,
- Dims: module.Dims{
- {ID: "device_%s_type_%s_attr_%s_decoded", Name: "%s"},
- },
- }
- deviceSmartAttributeNormalizedChartTmpl = module.Chart{
- ID: "device_%s_type_%s_smart_attr_%s_normalized",
- Title: "Device smart attribute normalized %s",
- Units: "value",
- Fam: "attr %s",
- Ctx: "smartctl.device_smart_attr_%s_normalized",
- Type: module.Line,
- Priority: prioDeviceSmartAttributeNormalized,
- Dims: module.Dims{
- {ID: "device_%s_type_%s_attr_%s_normalized", Name: "%s"},
- },
- }
-)
-
-func (s *Smartctl) addDeviceCharts(dev *smartDevice) {
- charts := module.Charts{}
-
- if cs := s.newDeviceCharts(dev); cs != nil && len(*cs) > 0 {
- if err := charts.Add(*cs...); err != nil {
- s.Warning(err)
- }
- }
- if cs := s.newDeviceSmartAttrCharts(dev); cs != nil && len(*cs) > 0 {
- if err := charts.Add(*cs...); err != nil {
- s.Warning(err)
- }
- }
-
- if err := s.Charts().Add(charts...); err != nil {
- s.Warning(err)
- }
-}
-
-func (s *Smartctl) removeDeviceCharts(scanDev *scanDevice) {
- px := fmt.Sprintf("device_%s_%s_", scanDev.shortName(), scanDev.typ)
-
- for _, chart := range *s.Charts() {
- if strings.HasPrefix(chart.ID, px) {
- chart.MarkRemove()
- chart.MarkNotCreated()
- }
- }
-}
-
-func (s *Smartctl) newDeviceCharts(dev *smartDevice) *module.Charts {
-
- charts := deviceChartsTmpl.Copy()
-
- if _, ok := dev.powerOnTime(); !ok {
- _ = charts.Remove(devicePowerOnTimeChartTmpl.ID)
- }
- if _, ok := dev.temperature(); !ok {
- _ = charts.Remove(deviceTemperatureChartTmpl.ID)
- }
- if _, ok := dev.powerCycleCount(); !ok {
- _ = charts.Remove(devicePowerOnTimeChartTmpl.ID)
- }
- if _, ok := dev.smartStatusPassed(); !ok {
- _ = charts.Remove(deviceSmartStatusChartTmpl.ID)
- }
- if _, ok := dev.ataSmartErrorLogCount(); !ok {
- _ = charts.Remove(deviceAtaSmartErrorLogCountChartTmpl.ID)
- }
-
- for _, chart := range *charts {
- chart.ID = fmt.Sprintf(chart.ID, dev.deviceName(), dev.deviceType())
- chart.Labels = []module.Label{
- {Key: "device_name", Value: dev.deviceName()},
- {Key: "device_type", Value: dev.deviceType()},
- {Key: "model_name", Value: dev.modelName()},
- {Key: "serial_number", Value: dev.serialNumber()},
- }
- for _, dim := range chart.Dims {
- dim.ID = fmt.Sprintf(dim.ID, dev.deviceName(), dev.deviceType())
- }
- }
-
- return charts
-}
-
-func (s *Smartctl) newDeviceSmartAttrCharts(dev *smartDevice) *module.Charts {
- attrs, ok := dev.ataSmartAttributeTable()
- if !ok {
- return nil
- }
- charts := module.Charts{}
-
- for _, attr := range attrs {
- if !isSmartAttrValid(attr) ||
- strings.HasPrefix(attr.name(), "Unknown") ||
- strings.HasPrefix(attr.name(), "Not_In_Use") {
- continue
- }
-
- cs := module.Charts{
- deviceSmartAttributeDecodedChartTmpl.Copy(),
- deviceSmartAttributeNormalizedChartTmpl.Copy(),
- }
-
- attrName := attributeNameMap(attr.name())
- cleanAttrName := cleanAttributeName(attrName)
-
- for _, chart := range cs {
- if chart.ID == deviceSmartAttributeDecodedChartTmpl.ID {
- chart.Units = attributeUnit(attrName)
- }
- chart.ID = fmt.Sprintf(chart.ID, dev.deviceName(), dev.deviceType(), cleanAttrName)
- chart.Title = fmt.Sprintf(chart.Title, attrName)
- chart.Fam = fmt.Sprintf(chart.Fam, cleanAttrName)
- chart.Ctx = fmt.Sprintf(chart.Ctx, cleanAttrName)
- chart.Labels = []module.Label{
- {Key: "device_name", Value: dev.deviceName()},
- {Key: "device_type", Value: dev.deviceType()},
- {Key: "model_name", Value: dev.modelName()},
- {Key: "serial_number", Value: dev.serialNumber()},
- }
- for _, dim := range chart.Dims {
- dim.ID = fmt.Sprintf(dim.ID, dev.deviceName(), dev.deviceType(), cleanAttrName)
- dim.Name = fmt.Sprintf(dim.Name, cleanAttrName)
- }
- }
-
- if err := charts.Add(cs...); err != nil {
- s.Warning(err)
- }
- }
-
- return &charts
-}
-
-var attrNameReplacer = strings.NewReplacer(" ", "_", "/", "_")
-
-func cleanAttributeName(attrName string) string {
- return strings.ToLower(attrNameReplacer.Replace(attrName))
-}
-
-func attributeUnit(attrName string) string {
- units := map[string]string{
- "Airflow_Temperature_Cel": "Celsius",
- "Case_Temperature": "Celsius",
- "Drive_Temperature": "Celsius",
- "Temperature_Case": "Celsius",
- "Temperature_Celsius": "Celsius",
- "Temperature_Internal": "Celsius",
- "Power_On_Hours": "hours",
- "Spin_Up_Time": "milliseconds",
- "Media_Wearout_Indicator": "percent",
- "Percent_Life_Remaining": "percent",
- "Percent_Lifetime_Remain": "percent",
- "Total_LBAs_Read": "sectors",
- "Total_LBAs_Written": "sectors",
- "Offline_Uncorrectable": "sectors",
- "Pending_Sector_Count": "sectors",
- "Reallocated_Sector_Ct": "sectors",
- "Current_Pending_Sector": "sectors",
- "Reported_Uncorrect": "errors",
- "Command_Timeout": "events",
- }
-
- if unit, ok := units[attrName]; ok {
- return unit
- }
-
- // TODO: convert to bytes during data collection? (examples: NAND_Writes_32MiB, Flash_Writes_GiB)
- if strings.HasSuffix(attrName, "MiB") || strings.HasSuffix(attrName, "GiB") {
- if strings.Contains(attrName, "Writes") {
- return "writes"
- }
- if strings.Contains(attrName, "Reads") {
- return "reads"
- }
- }
-
- if strings.Contains(attrName, "Error") {
- return "errors"
- }
-
- for _, s := range []string{"_Count", "_Cnt", "_Ct"} {
- if strings.HasSuffix(attrName, s) {
- return "events"
- }
- }
-
- return "value"
-}
-
-func attributeNameMap(attrName string) string {
- // TODO: Handle Vendor-Specific S.M.A.R.T. Attribute Naming
- // S.M.A.R.T. attribute names can vary slightly between vendors (e.g., "Thermal_Throttle_St" vs. "Thermal_Throttle_Status").
- // This function ensures consistent naming.
- return attrName
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/collect.go b/src/go/collectors/go.d.plugin/modules/smartctl/collect.go
deleted file mode 100644
index 79cbb13d0..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/collect.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- "fmt"
- "maps"
- "slices"
- "strconv"
- "strings"
- "time"
-
- "github.com/tidwall/gjson"
-)
-
-func (s *Smartctl) collect() (map[string]int64, error) {
- now := time.Now()
-
- if s.forceScan || s.isTimeToScan(now) {
- devices, err := s.scanDevices()
- if err != nil {
- return nil, err
- }
-
- for k, dev := range s.scannedDevices {
- if _, ok := devices[k]; !ok {
- delete(s.scannedDevices, k)
- delete(s.seenDevices, k)
- s.removeDeviceCharts(dev)
- }
- }
-
- s.forceDevicePoll = !maps.Equal(s.scannedDevices, devices)
- s.scannedDevices = devices
- s.lastScanTime = now
- s.forceScan = false
- }
-
- if s.forceDevicePoll || s.isTimeToPollDevices(now) {
- mx := make(map[string]int64)
-
- // TODO: make it concurrent
- for _, d := range s.scannedDevices {
- if err := s.collectScannedDevice(mx, d); err != nil {
- return nil, err
- }
- }
-
- s.forceDevicePoll = false
- s.lastDevicePollTime = now
- s.mx = mx
- }
-
- return s.mx, nil
-}
-
-func (s *Smartctl) collectScannedDevice(mx map[string]int64, scanDev *scanDevice) error {
- resp, err := s.exec.deviceInfo(scanDev.name, scanDev.typ, s.NoCheckPowerMode)
- if err != nil {
- if resp != nil && isDeviceOpenFailedNoSuchDevice(resp) {
- s.Infof("smartctl reported that device '%s' type '%s' no longer exists", scanDev.name, scanDev.typ)
- s.forceScan = true
- return nil
- }
- return fmt.Errorf("failed to get device info for '%s' type '%s': %v", scanDev.name, scanDev.typ, err)
- }
-
- if isDeviceInLowerPowerMode(resp) {
- s.Debugf("device '%s' type '%s' is in a low-power mode, skipping", scanDev.name, scanDev.typ)
- return nil
- }
-
- dev := newSmartDevice(resp)
- if !isSmartDeviceValid(dev) {
- return nil
- }
-
- if !s.seenDevices[scanDev.key()] {
- s.seenDevices[scanDev.key()] = true
- s.addDeviceCharts(dev)
- }
-
- s.collectSmartDevice(mx, dev)
-
- return nil
-}
-
-func (s *Smartctl) collectSmartDevice(mx map[string]int64, dev *smartDevice) {
- px := fmt.Sprintf("device_%s_type_%s_", dev.deviceName(), dev.deviceType())
-
- if v, ok := dev.powerOnTime(); ok {
- mx[px+"power_on_time"] = v
- }
- if v, ok := dev.temperature(); ok {
- mx[px+"temperature"] = v
- }
- if v, ok := dev.powerCycleCount(); ok {
- mx[px+"power_cycle_count"] = v
- }
- if v, ok := dev.smartStatusPassed(); ok {
- mx[px+"smart_status_passed"] = 0
- mx[px+"smart_status_failed"] = 0
- if v {
- mx[px+"smart_status_passed"] = 1
- } else {
- mx[px+"smart_status_failed"] = 1
- }
- }
- if v, ok := dev.ataSmartErrorLogCount(); ok {
- mx[px+"ata_smart_error_log_summary_count"] = v
- }
-
- if attrs, ok := dev.ataSmartAttributeTable(); ok {
- for _, attr := range attrs {
- if !isSmartAttrValid(attr) {
- continue
- }
- n := strings.ToLower(attr.name())
- n = strings.ReplaceAll(n, " ", "_")
- px := fmt.Sprintf("%sattr_%s_", px, n)
-
- if v, err := strconv.ParseInt(attr.value(), 10, 64); err == nil {
- mx[px+"normalized"] = v
- }
-
- if v, err := strconv.ParseInt(attr.rawValue(), 10, 64); err == nil {
- mx[px+"raw"] = v
- }
-
- rs := strings.TrimSpace(attr.rawString())
- if i := strings.IndexByte(rs, ' '); i != -1 {
- rs = rs[:i]
- }
- if v, err := strconv.ParseInt(rs, 10, 64); err == nil {
- mx[px+"decoded"] = v
- }
- }
- }
-}
-
-func (s *Smartctl) isTimeToScan(now time.Time) bool {
- return now.After(s.lastScanTime.Add(s.ScanEvery.Duration()))
-}
-
-func (s *Smartctl) isTimeToPollDevices(now time.Time) bool {
- return now.After(s.lastDevicePollTime.Add(s.PollDevicesEvery.Duration()))
-
-}
-
-func isSmartDeviceValid(d *smartDevice) bool {
- return d.deviceName() != "" && d.deviceType() != ""
-}
-
-func isSmartAttrValid(a *smartAttribute) bool {
- return a.id() != "" && a.name() != ""
-}
-
-func isDeviceInLowerPowerMode(r *gjson.Result) bool {
- if !isExitStatusHasBit(r, 1) {
- return false
- }
-
- messages := r.Get("smartctl.messages").Array()
-
- return slices.ContainsFunc(messages, func(msg gjson.Result) bool {
- text := msg.Get("string").String()
- return strings.HasPrefix(text, "Device is in") && strings.Contains(text, "mode")
- })
-}
-
-func isDeviceOpenFailedNoSuchDevice(r *gjson.Result) bool {
- if !isExitStatusHasBit(r, 1) {
- return false
- }
-
- messages := r.Get("smartctl.messages").Array()
-
- return slices.ContainsFunc(messages, func(msg gjson.Result) bool {
- text := msg.Get("string").String()
- return strings.HasSuffix(text, "No such device")
- })
-}
-
-func isExitStatusHasBit(r *gjson.Result, bit int) bool {
- // https://manpages.debian.org/bullseye/smartmontools/smartctl.8.en.html#EXIT_STATUS
- status := int(r.Get("smartctl.exit_status").Int())
- mask := 1 << bit
- return (status & mask) != 0
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/config_schema.json b/src/go/collectors/go.d.plugin/modules/smartctl/config_schema.json
deleted file mode 100644
index 8093cc5f8..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/config_schema.json
+++ /dev/null
@@ -1,99 +0,0 @@
-{
- "jsonSchema": {
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "Smartctl collector configuration.",
- "type": "object",
- "properties": {
- "update_every": {
- "title": "Update every",
- "description": "Interval for updating Netdata charts, measured in seconds. Collector might use cached data if less than **Devices poll interval**.",
- "type": "integer",
- "minimum": 1,
- "default": 10
- },
- "timeout": {
- "title": "Timeout",
- "description": "Timeout for executing the `smartctl` binary, specified in seconds.",
- "type": "number",
- "minimum": 0.5,
- "default": 5
- },
- "scan_every": {
- "title": "Scan interval",
- "description": "Interval for discovering new devices using `smartctl --scan`, measured in seconds.",
- "type": "number",
- "minimum": 1,
- "default": 900
- },
- "poll_devices_every": {
- "title": "Devices poll interval",
- "description": "Interval for gathering data for every device, measured in seconds. Data is cached for this interval.",
- "type": "number",
- "minimum": 1,
- "default": 300
- },
- "no_check_power_mode": {
- "title": "No check power mode",
- "description": "ATA only. Skip data collection when the device is in a low-power mode. Prevents unnecessary disk spin-up.",
- "type": "string",
- "enum": [
- "standby",
- "never",
- "sleep",
- "idle"
- ],
- "default": "standby"
- },
- "device_selector": {
- "title": "Device selector",
- "description": "Specifies a [pattern](https://github.com/netdata/netdata/tree/master/src/libnetdata/simple_pattern#readme) to match the 'info name' of devices as reported by `smartctl --scan --json`. Only devices whose 'info name' matches this pattern will be collected.",
- "type": "string",
- "minimum": 1,
- "default": "*"
- }
- },
- "additionalProperties": false,
- "patternProperties": {
- "^name$": {}
- }
- },
- "uiSchema": {
- "uiOptions": {
- "fullPage": true
- },
- "ui:flavour": "tabs",
- "ui:options": {
- "tabs": [
- {
- "title": "Base",
- "fields": [
- "update_every",
- "timeout",
- "scan_every",
- "poll_devices_every",
- "no_check_power_mode"
- ]
- },
- {
- "title": "Filtering",
- "fields": [
- "device_selector"
- ]
- }
- ]
- },
- "timeout": {
- "ui:help": "Accepts decimals for precise control (e.g., type 1.5 for 1.5 seconds)."
- },
- "no_check_power_mode": {
- "ui:help": "`never` - check the device always; `sleep` - check the device unless it is in SLEEP mode; `standby` - check the device unless it is in SLEEP or STANDBY mode; `idle` - check the device unless it is in SLEEP, STANDBY or IDLE mode.",
- "ui:widget": "radio",
- "ui:options": {
- "inline": true
- }
- },
- "device_selector": {
- "ui:help": "Leave blank or use `*` to collect data for all devices."
- }
- }
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/exec.go b/src/go/collectors/go.d.plugin/modules/smartctl/exec.go
deleted file mode 100644
index a90e1b529..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/exec.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- "context"
- "errors"
- "fmt"
- "os/exec"
- "time"
-
- "github.com/netdata/netdata/go/go.d.plugin/logger"
-
- "github.com/tidwall/gjson"
-)
-
-func newSmartctlCliExec(ndsudoPath string, timeout time.Duration, log *logger.Logger) *smartctlCliExec {
- return &smartctlCliExec{
- Logger: log,
- ndsudoPath: ndsudoPath,
- timeout: timeout,
- }
-}
-
-type smartctlCliExec struct {
- *logger.Logger
-
- ndsudoPath string
- timeout time.Duration
-}
-
-func (e *smartctlCliExec) scan() (*gjson.Result, error) {
- return e.execute("smartctl-json-scan")
-}
-
-func (e *smartctlCliExec) deviceInfo(deviceName, deviceType, powerMode string) (*gjson.Result, error) {
- return e.execute("smartctl-json-device-info",
- "--deviceName", deviceName,
- "--deviceType", deviceType,
- "--powerMode", powerMode,
- )
-}
-
-func (e *smartctlCliExec) execute(args ...string) (*gjson.Result, error) {
- ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
- defer cancel()
-
- cmd := exec.CommandContext(ctx, e.ndsudoPath, args...)
- e.Debugf("executing '%s'", cmd)
-
- bs, err := cmd.Output()
- if err != nil {
- if errors.Is(err, context.DeadlineExceeded) || isExecExitCode(err, 1) || len(bs) == 0 {
- return nil, fmt.Errorf("'%s' execution failed: %v", cmd, err)
- }
- }
- if len(bs) == 0 {
- return nil, fmt.Errorf("'%s' returned no output", cmd)
- }
-
- if !gjson.ValidBytes(bs) {
- return nil, fmt.Errorf("'%s' returned invalid JSON output", cmd)
- }
-
- res := gjson.ParseBytes(bs)
- if !res.Get("smartctl.exit_status").Exists() {
- return nil, fmt.Errorf("'%s' returned unexpected data", cmd)
- }
-
- for _, msg := range res.Get("smartctl.messages").Array() {
- if msg.Get("severity").String() == "error" {
- return &res, fmt.Errorf("'%s' reported an error: %s", cmd, msg.Get("string"))
- }
- }
-
- return &res, nil
-}
-
-func isExecExitCode(err error, exitCode int) bool {
- var v *exec.ExitError
- return errors.As(err, &v) && v.ExitCode() == exitCode
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/init.go b/src/go/collectors/go.d.plugin/modules/smartctl/init.go
deleted file mode 100644
index b5d4ebfe3..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/init.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- "fmt"
- "os"
- "path/filepath"
-
- "github.com/netdata/netdata/go/go.d.plugin/agent/executable"
- "github.com/netdata/netdata/go/go.d.plugin/pkg/matcher"
-)
-
-func (s *Smartctl) validateConfig() error {
- switch s.NoCheckPowerMode {
- case "never", "sleep", "standby", "idle":
- default:
- return fmt.Errorf("invalid power mode '%s'", s.NoCheckPowerMode)
- }
- return nil
-}
-
-func (s *Smartctl) initDeviceSelector() (matcher.Matcher, error) {
- if s.DeviceSelector == "" {
- return matcher.TRUE(), nil
- }
-
- m, err := matcher.NewSimplePatternsMatcher(s.DeviceSelector)
- if err != nil {
- return nil, err
- }
-
- return m, nil
-}
-
-func (s *Smartctl) initSmartctlCli() (smartctlCli, error) {
- ndsudoPath := filepath.Join(executable.Directory, "ndsudo")
- if _, err := os.Stat(ndsudoPath); err != nil {
- return nil, fmt.Errorf("ndsudo executable not found: %v", err)
-
- }
-
- smartctlExec := newSmartctlCliExec(ndsudoPath, s.Timeout.Duration(), s.Logger)
-
- return smartctlExec, nil
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/integrations/s.m.a.r.t..md b/src/go/collectors/go.d.plugin/modules/smartctl/integrations/s.m.a.r.t..md
deleted file mode 100644
index 482fedbd1..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/integrations/s.m.a.r.t..md
+++ /dev/null
@@ -1,181 +0,0 @@
-<!--startmeta
-custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/smartctl/README.md"
-meta_yaml: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/smartctl/metadata.yaml"
-sidebar_label: "S.M.A.R.T."
-learn_status: "Published"
-learn_rel_path: "Collecting Metrics/Hardware Devices and Sensors"
-most_popular: False
-message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE COLLECTOR'S metadata.yaml FILE"
-endmeta-->
-
-# S.M.A.R.T.
-
-
-<img src="https://netdata.cloud/img/smart.png" width="150"/>
-
-
-Plugin: go.d.plugin
-Module: smartctl
-
-<img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" />
-
-## Overview
-
-This collector monitors the health status of storage devices by analyzing S.M.A.R.T. (Self-Monitoring, Analysis, and Reporting Technology) counters.
-It relies on the [`smartctl`](https://linux.die.net/man/8/smartctl) CLI tool but avoids directly executing the binary.
-Instead, it utilizes `ndsudo`, a Netdata helper specifically designed to run privileged commands securely within the Netdata environment.
-This approach eliminates the need to use `sudo`, improving security and potentially simplifying permission management.
-
-Executed commands:
-- `smartctl --json --scan`
-- `smartctl --json --all {deviceName} --device {deviceType} --nocheck {powerMode}`
-
-
-
-
-This collector is supported on all platforms.
-
-This collector only supports collecting metrics from a single instance of this integration.
-
-
-### Default Behavior
-
-#### Auto-Detection
-
-This integration doesn't support auto-detection.
-
-#### Limits
-
-The default configuration for this integration does not impose any limits on data collection.
-
-#### Performance Impact
-
-The default configuration for this integration is not expected to impose a significant performance impact on the system.
-
-
-## Metrics
-
-Metrics grouped by *scope*.
-
-The scope defines the instance that the metric belongs to. An instance is uniquely identified by a set of labels.
-
-
-
-### Per controller
-
-These metrics refer to the Storage Device.
-
-Labels:
-
-| Label | Description |
-|:-----------|:----------------|
-| device_name | Device name |
-| device_type | Device type |
-| model_name | Model name |
-| serial_number | Serial number |
-
-Metrics:
-
-| Metric | Dimensions | Unit |
-|:------|:----------|:----|
-| smartctl.device_smart_status | passed, failed | status |
-| smartctl.device_ata_smart_error_log_count | error_log | logs |
-| smartctl.device_power_on_time | power_on_time | seconds |
-| smartctl.device_temperature | temperature | Celsius |
-| smartctl.device_power_cycles_count | power | cycles |
-| smartctl.device_smart_attr_{attribute_name} | {attribute_name} | {attribute_unit} |
-| smartctl.device_smart_attr_{attribute_name}_normalized | {attribute_name} | value |
-
-
-
-## Alerts
-
-There are no alerts configured by default for this integration.
-
-
-## Setup
-
-### Prerequisites
-
-#### Install smartmontools (v7.0+)
-
-Install `smartmontools` version 7.0 or later using your distribution's package manager. Version 7.0 introduced the `--json` output mode, which is required for this collector to function properly.
-
-
-
-### Configuration
-
-#### File
-
-The configuration file name for this integration is `go.d/smartctl.conf`.
-
-
-You can edit the configuration file using the `edit-config` script from the
-Netdata [config directory](/docs/netdata-agent/configuration/README.md#the-netdata-config-directory).
-
-```bash
-cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
-sudo ./edit-config go.d/smartctl.conf
-```
-#### Options
-
-The following options can be defined globally: update_every.
-
-
-<details open><summary>Config options</summary>
-
-| Name | Description | Default | Required |
-|:----|:-----------|:-------|:--------:|
-| update_every | interval for updating Netdata charts, measured in seconds. Collector might use cached data if less than **Devices poll interval**. | 10 | no |
-| timeout | smartctl binary execution timeout. | 5 | no |
-| scan_every | interval for discovering new devices using `smartctl --scan`, measured in seconds. | 900 | no |
-| poll_devices_every | interval for gathering data for every device, measured in seconds. Data is cached for this interval. | 300 | no |
-| device_selector | Specifies a pattern to match the 'info name' of devices as reported by `smartctl --scan --json`. | * | no |
-
-</details>
-
-#### Examples
-
-##### Custom devices poll interval
-
-Allows you to override the default devices poll interval (data collection).
-
-<details open><summary>Config</summary>
-
-```yaml
-jobs:
- - name: smartctl
- devices_poll_interval: 60 # Collect S.M.A.R.T statistics every 60 seconds
-
-```
-</details>
-
-
-
-## Troubleshooting
-
-### Debug Mode
-
-To troubleshoot issues with the `smartctl` collector, run the `go.d.plugin` with the debug option enabled. The output
-should give you clues as to why the collector isn't working.
-
-- Navigate to the `plugins.d` directory, usually at `/usr/libexec/netdata/plugins.d/`. If that's not the case on
- your system, open `netdata.conf` and look for the `plugins` setting under `[directories]`.
-
- ```bash
- cd /usr/libexec/netdata/plugins.d/
- ```
-
-- Switch to the `netdata` user.
-
- ```bash
- sudo -u netdata -s
- ```
-
-- Run the `go.d.plugin` to debug the collector:
-
- ```bash
- ./go.d.plugin -d -m smartctl
- ```
-
-
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/metadata.yaml b/src/go/collectors/go.d.plugin/modules/smartctl/metadata.yaml
deleted file mode 100644
index 6d409ec56..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/metadata.yaml
+++ /dev/null
@@ -1,161 +0,0 @@
-plugin_name: go.d.plugin
-modules:
- - meta:
- id: collector-go.d.plugin-smartctl
- plugin_name: go.d.plugin
- module_name: smartctl
- monitored_instance:
- name: S.M.A.R.T.
- link: "https://linux.die.net/man/8/smartd"
- icon_filename: "smart.png"
- categories:
- - data-collection.hardware-devices-and-sensors
- keywords:
- - smart
- - S.M.A.R.T.
- - SCSI devices
- - ATA devices
- related_resources:
- integrations:
- list: []
- info_provided_to_referring_integrations:
- description: ""
- most_popular: false
- overview:
- data_collection:
- metrics_description: |
- This collector monitors the health status of storage devices by analyzing S.M.A.R.T. (Self-Monitoring, Analysis, and Reporting Technology) counters.
- It relies on the [`smartctl`](https://linux.die.net/man/8/smartctl) CLI tool but avoids directly executing the binary.
- Instead, it utilizes `ndsudo`, a Netdata helper specifically designed to run privileged commands securely within the Netdata environment.
- This approach eliminates the need to use `sudo`, improving security and potentially simplifying permission management.
-
- Executed commands:
- - `smartctl --json --scan`
- - `smartctl --json --all {deviceName} --device {deviceType} --nocheck {powerMode}`
- method_description: ""
- supported_platforms:
- include: []
- exclude: []
- multi_instance: false
- additional_permissions:
- description: ""
- default_behavior:
- auto_detection:
- description: ""
- limits:
- description: ""
- performance_impact:
- description: ""
- setup:
- prerequisites:
- list:
- - title: Install smartmontools (v7.0+)
- description: |
- Install `smartmontools` version 7.0 or later using your distribution's package manager. Version 7.0 introduced the `--json` output mode, which is required for this collector to function properly.
- configuration:
- file:
- name: go.d/smartctl.conf
- options:
- description: |
- The following options can be defined globally: update_every.
- folding:
- title: Config options
- enabled: true
- list:
- - name: update_every
- description: interval for updating Netdata charts, measured in seconds. Collector might use cached data if less than **Devices poll interval**.
- default_value: 10
- required: false
- - name: timeout
- description: smartctl binary execution timeout.
- default_value: 5
- required: false
- - name: scan_every
- description: interval for discovering new devices using `smartctl --scan`, measured in seconds.
- default_value: 900
- required: false
- - name: poll_devices_every
- description: interval for gathering data for every device, measured in seconds. Data is cached for this interval.
- default_value: 300
- required: false
- - name: device_selector
- description: "Specifies a pattern to match the 'info name' of devices as reported by `smartctl --scan --json`."
- default_value: "*"
- required: false
- examples:
- folding:
- title: Config
- enabled: true
- list:
- - name: Custom devices poll interval
- description: Allows you to override the default devices poll interval (data collection).
- config: |
- jobs:
- - name: smartctl
- devices_poll_interval: 60 # Collect S.M.A.R.T statistics every 60 seconds
- troubleshooting:
- problems:
- list: []
- alerts: []
- metrics:
- folding:
- title: Metrics
- enabled: false
- description: ""
- availability: []
- scopes:
- - name: controller
- description: These metrics refer to the Storage Device.
- labels:
- - name: device_name
- description: Device name
- - name: device_type
- description: Device type
- - name: model_name
- description: Model name
- - name: serial_number
- description: Serial number
- metrics:
- - name: smartctl.device_smart_status
- description: Device smart status
- unit: status
- chart_type: line
- dimensions:
- - name: passed
- - name: failed
- - name: smartctl.device_ata_smart_error_log_count
- description: Device ATA smart error log count
- unit: logs
- chart_type: line
- dimensions:
- - name: error_log
- - name: smartctl.device_power_on_time
- description: Device power on time
- unit: seconds
- chart_type: line
- dimensions:
- - name: power_on_time
- - name: smartctl.device_temperature
- description: Device temperature
- unit: Celsius
- chart_type: line
- dimensions:
- - name: temperature
- - name: smartctl.device_power_cycles_count
- description: Device power cycles
- unit: cycles
- chart_type: line
- dimensions:
- - name: power
- - name: smartctl.device_smart_attr_{attribute_name}
- description: Device smart attribute {attribute_name}
- unit: '{attribute_unit}'
- chart_type: line
- dimensions:
- - name: '{attribute_name}'
- - name: smartctl.device_smart_attr_{attribute_name}_normalized
- description: Device smart attribute {attribute_name} normalized
- unit: value
- chart_type: line
- dimensions:
- - name: '{attribute_name}'
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/scan.go b/src/go/collectors/go.d.plugin/modules/smartctl/scan.go
deleted file mode 100644
index 9310938f6..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/scan.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- "errors"
- "fmt"
- "strings"
-)
-
-type scanDevice struct {
- name string
- infoName string
- typ string
-}
-
-func (s *scanDevice) key() string {
- return fmt.Sprintf("%s|%s", s.name, s.typ)
-}
-
-func (s *scanDevice) shortName() string {
- return strings.TrimPrefix(s.name, "/dev/")
-}
-
-func (s *Smartctl) scanDevices() (map[string]*scanDevice, error) {
- resp, err := s.exec.scan()
- if err != nil {
- return nil, fmt.Errorf("failed to scan devices: %v", err)
- }
-
- devices := make(map[string]*scanDevice)
-
- for _, d := range resp.Get("devices").Array() {
- dev := &scanDevice{
- name: d.Get("name").String(),
- infoName: d.Get("info_name").String(),
- typ: d.Get("type").String(), // guessed type (we do '--scan' not '--scan-open')
- }
-
- if dev.name == "" || dev.typ == "" {
- s.Warningf("device info missing required fields (name: '%s', type: '%s'), skipping", dev.name, dev.typ)
- continue
- }
-
- if !s.deviceSr.MatchString(dev.infoName) {
- s.Debugf("device %s does not match selector, skipping it", dev.infoName)
- continue
- }
-
- if dev.typ == "scsi" {
- // `smartctl --scan` attempts to guess the device type based on the path, but this can be unreliable.
- // Accurate device type information is crucial because we use the `--device` option to gather data.
- // Using the wrong type can lead to issues.
- // For example, using 'scsi' for 'sat' devices prevents `smartctl` from issuing the necessary ATA commands.
- resp, _ := s.exec.deviceInfo(dev.name, dev.typ, s.NoCheckPowerMode)
- if resp != nil && isExitStatusHasBit(resp, 2) {
- correctType := "sat"
- s.Debugf("changing device '%s' type '%s' -> '%s'", dev.name, dev.typ, correctType)
- dev.typ = correctType
- }
- }
-
- s.Debugf("smartctl scan found device '%s' type '%s' info_name '%s'", dev.name, dev.typ, dev.infoName)
-
- devices[dev.key()] = dev
- }
-
- if len(devices) == 0 {
- return nil, errors.New("no devices found during scan")
- }
-
- s.Debugf("smartctl scan found %d devices", len(devices))
-
- return devices, nil
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/smart_device.go b/src/go/collectors/go.d.plugin/modules/smartctl/smart_device.go
deleted file mode 100644
index 87306bab9..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/smart_device.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- "strings"
-
- "github.com/tidwall/gjson"
-)
-
-func newSmartDevice(deviceData *gjson.Result) *smartDevice {
- return &smartDevice{
- data: deviceData,
- }
-}
-
-type smartDevice struct {
- data *gjson.Result
-}
-
-func (d *smartDevice) deviceName() string {
- v := d.data.Get("device.name").String()
- return strings.TrimPrefix(v, "/dev/")
-}
-
-func (d *smartDevice) deviceType() string {
- return d.data.Get("device.type").String()
-}
-
-func (d *smartDevice) deviceProtocol() string {
- return d.data.Get("device.protocol").String()
-}
-
-func (d *smartDevice) serialNumber() string {
- return d.data.Get("serial_number").String()
-}
-
-func (d *smartDevice) modelName() string {
- for _, s := range []string{"model_name", "scsi_model_name"} {
- if v := d.data.Get(s); v.Exists() {
- return v.String()
- }
- }
- return "unknown"
-}
-
-func (d *smartDevice) powerOnTime() (int64, bool) {
- h := d.data.Get("power_on_time.hours")
- if !h.Exists() {
- return 0, false
- }
- m := d.data.Get("power_on_time.minutes")
- return h.Int()*60*60 + m.Int()*60, true
-}
-
-func (d *smartDevice) temperature() (int64, bool) {
- v := d.data.Get("temperature.current")
- return v.Int(), v.Exists()
-}
-
-func (d *smartDevice) powerCycleCount() (int64, bool) {
- for _, s := range []string{"power_cycle_count", "scsi_start_stop_cycle_counter.accumulated_start_stop_cycles"} {
- if v := d.data.Get(s); v.Exists() {
- return v.Int(), true
- }
- }
- return 0, false
-}
-
-func (d *smartDevice) smartStatusPassed() (bool, bool) {
- v := d.data.Get("smart_status.passed")
- return v.Bool(), v.Exists()
-}
-
-func (d *smartDevice) ataSmartErrorLogCount() (int64, bool) {
- v := d.data.Get("ata_smart_error_log.summary.count")
- return v.Int(), v.Exists()
-}
-
-func (d *smartDevice) ataSmartAttributeTable() ([]*smartAttribute, bool) {
- table := d.data.Get("ata_smart_attributes.table")
- if !table.Exists() || !table.IsArray() {
- return nil, false
- }
-
- var attrs []*smartAttribute
-
- for _, data := range table.Array() {
- attrs = append(attrs, newSmartDeviceAttribute(data))
- }
-
- return attrs, true
-}
-
-func newSmartDeviceAttribute(attrData gjson.Result) *smartAttribute {
- return &smartAttribute{
- data: attrData,
- }
-}
-
-type smartAttribute struct {
- data gjson.Result
-}
-
-func (a *smartAttribute) id() string {
- return a.data.Get("id").String()
-}
-
-func (a *smartAttribute) name() string {
- return a.data.Get("name").String()
-}
-
-func (a *smartAttribute) value() string {
- return a.data.Get("value").String()
-}
-
-func (a *smartAttribute) rawValue() string {
- return a.data.Get("raw.value").String()
-}
-
-func (a *smartAttribute) rawString() string {
- return a.data.Get("raw.string").String()
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/smartctl.go b/src/go/collectors/go.d.plugin/modules/smartctl/smartctl.go
deleted file mode 100644
index 4fb70666b..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/smartctl.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- _ "embed"
- "errors"
- "time"
-
- "github.com/netdata/netdata/go/go.d.plugin/agent/module"
- "github.com/netdata/netdata/go/go.d.plugin/pkg/matcher"
- "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
-
- "github.com/tidwall/gjson"
-)
-
-//go:embed "config_schema.json"
-var configSchema string
-
-func init() {
- module.Register("smartctl", module.Creator{
- JobConfigSchema: configSchema,
- Defaults: module.Defaults{
- UpdateEvery: 10,
- },
- Create: func() module.Module { return New() },
- Config: func() any { return &Config{} },
- })
-}
-
-func New() *Smartctl {
- return &Smartctl{
- Config: Config{
- Timeout: web.Duration(time.Second * 5),
- ScanEvery: web.Duration(time.Minute * 15),
- PollDevicesEvery: web.Duration(time.Minute * 5),
- NoCheckPowerMode: "standby",
- DeviceSelector: "*",
- },
- charts: &module.Charts{},
- deviceSr: matcher.TRUE(),
- seenDevices: make(map[string]bool),
- }
-}
-
-type Config struct {
- UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
- Timeout web.Duration `yaml:"timeout,omitempty" json:"timeout"`
- ScanEvery web.Duration `yaml:"scan_every,omitempty" json:"scan_every"`
- PollDevicesEvery web.Duration `yaml:"poll_devices_every,omitempty" json:"poll_devices_every"`
- NoCheckPowerMode string `yaml:"no_check_power_mode,omitempty" json:"no_check_power_mode"`
- DeviceSelector string `yaml:"device_selector,omitempty" json:"device_selector"`
-}
-
-type (
- Smartctl struct {
- module.Base
- Config `yaml:",inline" data:""`
-
- charts *module.Charts
-
- exec smartctlCli
-
- deviceSr matcher.Matcher
-
- lastScanTime time.Time
- forceScan bool
- scannedDevices map[string]*scanDevice
-
- lastDevicePollTime time.Time
- forceDevicePoll bool
-
- seenDevices map[string]bool
- mx map[string]int64
- }
- smartctlCli interface {
- scan() (*gjson.Result, error)
- deviceInfo(deviceName, deviceType, powerMode string) (*gjson.Result, error)
- }
-)
-
-func (s *Smartctl) Configuration() any {
- return s.Config
-}
-
-func (s *Smartctl) Init() error {
- if err := s.validateConfig(); err != nil {
- s.Errorf("config validation error: %s", err)
- return err
- }
-
- sr, err := s.initDeviceSelector()
- if err != nil {
- s.Errorf("device selector initialization: %v", err)
- return err
- }
- s.deviceSr = sr
-
- smartctlExec, err := s.initSmartctlCli()
- if err != nil {
- s.Errorf("smartctl exec initialization: %v", err)
- return err
- }
- s.exec = smartctlExec
-
- return nil
-}
-
-func (s *Smartctl) Check() error {
- mx, err := s.collect()
- if err != nil {
- s.Error(err)
- return err
- }
-
- if len(mx) == 0 {
- return errors.New("no metrics collected")
- }
-
- return nil
-}
-
-func (s *Smartctl) Charts() *module.Charts {
- return s.charts
-}
-
-func (s *Smartctl) Collect() map[string]int64 {
- mx, err := s.collect()
- if err != nil {
- s.Error(err)
- }
-
- if len(mx) == 0 {
- return nil
- }
-
- return mx
-}
-
-func (s *Smartctl) Cleanup() {}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/smartctl_test.go b/src/go/collectors/go.d.plugin/modules/smartctl/smartctl_test.go
deleted file mode 100644
index 9666924bf..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/smartctl_test.go
+++ /dev/null
@@ -1,436 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package smartctl
-
-import (
- "fmt"
- "os"
- "testing"
- "time"
-
- "github.com/netdata/netdata/go/go.d.plugin/agent/module"
- "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "github.com/tidwall/gjson"
-)
-
-var (
- dataConfigJSON, _ = os.ReadFile("testdata/config.json")
- dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
-
- dataTypeSataScan, _ = os.ReadFile("testdata/type-sat/scan.json")
- dataTypeSataDeviceHDDSda, _ = os.ReadFile("testdata/type-sat/device-hdd-sda.json")
- dataTypeSataDeviceSSDSdc, _ = os.ReadFile("testdata/type-sat/device-ssd-sdc.json")
-
- dataTypeNvmeScan, _ = os.ReadFile("testdata/type-nvme/scan.json")
- dataTypeNvmeDeviceNvme0, _ = os.ReadFile("testdata/type-nvme/device-nvme0.json")
-)
-
-func Test_testDataIsValid(t *testing.T) {
- for name, data := range map[string][]byte{
- "dataConfigJSON": dataConfigJSON,
- "dataConfigYAML": dataConfigYAML,
-
- "dataTypeSataScan": dataTypeSataScan,
- "dataTypeSataDeviceHDDSda": dataTypeSataDeviceHDDSda,
- "dataTypeSataDeviceSSDSdc": dataTypeSataDeviceSSDSdc,
-
- "dataTypeNvmeScan": dataTypeNvmeScan,
- "dataTypeNvmeDeviceNvme0": dataTypeNvmeDeviceNvme0,
- } {
- require.NotNil(t, data, name)
- }
-}
-
-func TestSmartctl_ConfigurationSerialize(t *testing.T) {
- module.TestConfigurationSerialize(t, &Smartctl{}, dataConfigJSON, dataConfigYAML)
-}
-
-func TestSmartctl_Init(t *testing.T) {
- tests := map[string]struct {
- config Config
- wantFail bool
- }{
- "fails if invalid power mode": {
- wantFail: true,
- config: func() Config {
- cfg := New().Config
- cfg.NoCheckPowerMode = "invalid"
- return cfg
- }(),
- },
- "fails if 'ndsudo' not found": {
- wantFail: true,
- config: New().Config,
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- smart := New()
-
- if test.wantFail {
- assert.Error(t, smart.Init())
- } else {
- assert.NoError(t, smart.Init())
- }
- })
- }
-}
-
-func TestSmartctl_Cleanup(t *testing.T) {
- tests := map[string]struct {
- prepare func() *Smartctl
- }{
- "not initialized exec": {
- prepare: func() *Smartctl {
- return New()
- },
- },
- "after check": {
- prepare: func() *Smartctl {
- smart := New()
- smart.exec = prepareMockOkTypeSata()
- _ = smart.Check()
- return smart
- },
- },
- "after collect": {
- prepare: func() *Smartctl {
- smart := New()
- smart.exec = prepareMockOkTypeSata()
- _ = smart.Collect()
- return smart
- },
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- smart := test.prepare()
-
- assert.NotPanics(t, smart.Cleanup)
- })
- }
-}
-
-func TestSmartctl_Check(t *testing.T) {
- tests := map[string]struct {
- prepareMock func() *mockSmartctlCliExec
- wantFail bool
- }{
- "success type sata devices": {
- wantFail: false,
- prepareMock: prepareMockOkTypeSata,
- },
- "success type nvme devices": {
- wantFail: false,
- prepareMock: prepareMockOkTypeNvme,
- },
- "error on scan": {
- wantFail: true,
- prepareMock: prepareMockErrOnScan,
- },
- "unexpected response on scan": {
- wantFail: true,
- prepareMock: prepareMockUnexpectedResponse,
- },
- "empty response on scan": {
- wantFail: true,
- prepareMock: prepareMockEmptyResponse,
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- smart := New()
- mock := test.prepareMock()
- smart.exec = mock
-
- if test.wantFail {
- assert.Error(t, smart.Check())
- } else {
- assert.NoError(t, smart.Check())
- }
- })
- }
-}
-
-func TestSmartctl_Collect(t *testing.T) {
- tests := map[string]struct {
- prepareMock func() *mockSmartctlCliExec
- wantMetrics map[string]int64
- wantCharts int
- }{
- "success type sata devices": {
- prepareMock: prepareMockOkTypeSata,
- wantCharts: 68,
- wantMetrics: map[string]int64{
- "device_sda_type_sat_ata_smart_error_log_summary_count": 0,
- "device_sda_type_sat_attr_current_pending_sector_decoded": 0,
- "device_sda_type_sat_attr_current_pending_sector_normalized": 100,
- "device_sda_type_sat_attr_current_pending_sector_raw": 0,
- "device_sda_type_sat_attr_load_cycle_count_decoded": 360,
- "device_sda_type_sat_attr_load_cycle_count_normalized": 100,
- "device_sda_type_sat_attr_load_cycle_count_raw": 360,
- "device_sda_type_sat_attr_offline_uncorrectable_decoded": 0,
- "device_sda_type_sat_attr_offline_uncorrectable_normalized": 100,
- "device_sda_type_sat_attr_offline_uncorrectable_raw": 0,
- "device_sda_type_sat_attr_power-off_retract_count_decoded": 360,
- "device_sda_type_sat_attr_power-off_retract_count_normalized": 100,
- "device_sda_type_sat_attr_power-off_retract_count_raw": 360,
- "device_sda_type_sat_attr_power_cycle_count_decoded": 12,
- "device_sda_type_sat_attr_power_cycle_count_normalized": 100,
- "device_sda_type_sat_attr_power_cycle_count_raw": 12,
- "device_sda_type_sat_attr_power_on_hours_decoded": 8244,
- "device_sda_type_sat_attr_power_on_hours_normalized": 99,
- "device_sda_type_sat_attr_power_on_hours_raw": 8244,
- "device_sda_type_sat_attr_raw_read_error_rate_decoded": 0,
- "device_sda_type_sat_attr_raw_read_error_rate_normalized": 100,
- "device_sda_type_sat_attr_raw_read_error_rate_raw": 0,
- "device_sda_type_sat_attr_reallocated_event_count_decoded": 0,
- "device_sda_type_sat_attr_reallocated_event_count_normalized": 100,
- "device_sda_type_sat_attr_reallocated_event_count_raw": 0,
- "device_sda_type_sat_attr_reallocated_sector_ct_decoded": 0,
- "device_sda_type_sat_attr_reallocated_sector_ct_normalized": 100,
- "device_sda_type_sat_attr_reallocated_sector_ct_raw": 0,
- "device_sda_type_sat_attr_seek_error_rate_decoded": 0,
- "device_sda_type_sat_attr_seek_error_rate_normalized": 100,
- "device_sda_type_sat_attr_seek_error_rate_raw": 0,
- "device_sda_type_sat_attr_seek_time_performance_decoded": 15,
- "device_sda_type_sat_attr_seek_time_performance_normalized": 140,
- "device_sda_type_sat_attr_seek_time_performance_raw": 15,
- "device_sda_type_sat_attr_spin_retry_count_decoded": 0,
- "device_sda_type_sat_attr_spin_retry_count_normalized": 100,
- "device_sda_type_sat_attr_spin_retry_count_raw": 0,
- "device_sda_type_sat_attr_spin_up_time_decoded": 281,
- "device_sda_type_sat_attr_spin_up_time_normalized": 86,
- "device_sda_type_sat_attr_spin_up_time_raw": 25788088601,
- "device_sda_type_sat_attr_start_stop_count_decoded": 12,
- "device_sda_type_sat_attr_start_stop_count_normalized": 100,
- "device_sda_type_sat_attr_start_stop_count_raw": 12,
- "device_sda_type_sat_attr_temperature_celsius_decoded": 49,
- "device_sda_type_sat_attr_temperature_celsius_normalized": 43,
- "device_sda_type_sat_attr_temperature_celsius_raw": 240519741489,
- "device_sda_type_sat_attr_throughput_performance_decoded": 48,
- "device_sda_type_sat_attr_throughput_performance_normalized": 148,
- "device_sda_type_sat_attr_throughput_performance_raw": 48,
- "device_sda_type_sat_attr_udma_crc_error_count_decoded": 0,
- "device_sda_type_sat_attr_udma_crc_error_count_normalized": 100,
- "device_sda_type_sat_attr_udma_crc_error_count_raw": 0,
- "device_sda_type_sat_attr_unknown_attribute_decoded": 100,
- "device_sda_type_sat_attr_unknown_attribute_normalized": 100,
- "device_sda_type_sat_attr_unknown_attribute_raw": 100,
- "device_sda_type_sat_power_cycle_count": 12,
- "device_sda_type_sat_power_on_time": 29678400,
- "device_sda_type_sat_smart_status_failed": 0,
- "device_sda_type_sat_smart_status_passed": 1,
- "device_sda_type_sat_temperature": 49,
- "device_sdc_type_sat_ata_smart_error_log_summary_count": 0,
- "device_sdc_type_sat_attr_available_reservd_space_decoded": 100,
- "device_sdc_type_sat_attr_available_reservd_space_normalized": 100,
- "device_sdc_type_sat_attr_available_reservd_space_raw": 100,
- "device_sdc_type_sat_attr_command_timeout_decoded": 0,
- "device_sdc_type_sat_attr_command_timeout_normalized": 100,
- "device_sdc_type_sat_attr_command_timeout_raw": 0,
- "device_sdc_type_sat_attr_end-to-end_error_decoded": 0,
- "device_sdc_type_sat_attr_end-to-end_error_normalized": 100,
- "device_sdc_type_sat_attr_end-to-end_error_raw": 0,
- "device_sdc_type_sat_attr_media_wearout_indicator_decoded": 65406,
- "device_sdc_type_sat_attr_media_wearout_indicator_normalized": 100,
- "device_sdc_type_sat_attr_media_wearout_indicator_raw": 65406,
- "device_sdc_type_sat_attr_power_cycle_count_decoded": 13,
- "device_sdc_type_sat_attr_power_cycle_count_normalized": 100,
- "device_sdc_type_sat_attr_power_cycle_count_raw": 13,
- "device_sdc_type_sat_attr_power_on_hours_decoded": 8244,
- "device_sdc_type_sat_attr_power_on_hours_normalized": 100,
- "device_sdc_type_sat_attr_power_on_hours_raw": 8244,
- "device_sdc_type_sat_attr_reallocated_sector_ct_decoded": 0,
- "device_sdc_type_sat_attr_reallocated_sector_ct_normalized": 100,
- "device_sdc_type_sat_attr_reallocated_sector_ct_raw": 0,
- "device_sdc_type_sat_attr_reported_uncorrect_decoded": 0,
- "device_sdc_type_sat_attr_reported_uncorrect_normalized": 100,
- "device_sdc_type_sat_attr_reported_uncorrect_raw": 0,
- "device_sdc_type_sat_attr_temperature_celsius_decoded": 27,
- "device_sdc_type_sat_attr_temperature_celsius_normalized": 73,
- "device_sdc_type_sat_attr_temperature_celsius_raw": 184684970011,
- "device_sdc_type_sat_attr_total_lbas_read_decoded": 76778,
- "device_sdc_type_sat_attr_total_lbas_read_normalized": 253,
- "device_sdc_type_sat_attr_total_lbas_read_raw": 76778,
- "device_sdc_type_sat_attr_total_lbas_written_decoded": 173833,
- "device_sdc_type_sat_attr_total_lbas_written_normalized": 253,
- "device_sdc_type_sat_attr_total_lbas_written_raw": 173833,
- "device_sdc_type_sat_attr_udma_crc_error_count_decoded": 0,
- "device_sdc_type_sat_attr_udma_crc_error_count_normalized": 100,
- "device_sdc_type_sat_attr_udma_crc_error_count_raw": 0,
- "device_sdc_type_sat_attr_unknown_attribute_decoded": 0,
- "device_sdc_type_sat_attr_unknown_attribute_normalized": 0,
- "device_sdc_type_sat_attr_unknown_attribute_raw": 0,
- "device_sdc_type_sat_attr_unknown_ssd_attribute_decoded": 4694419309637,
- "device_sdc_type_sat_attr_unknown_ssd_attribute_normalized": 4,
- "device_sdc_type_sat_attr_unknown_ssd_attribute_raw": 4694419309637,
- "device_sdc_type_sat_power_cycle_count": 13,
- "device_sdc_type_sat_power_on_time": 29678400,
- "device_sdc_type_sat_smart_status_failed": 0,
- "device_sdc_type_sat_smart_status_passed": 1,
- "device_sdc_type_sat_temperature": 27,
- },
- },
- "success type nvme devices": {
- prepareMock: prepareMockOkTypeNvme,
- wantCharts: 4,
- wantMetrics: map[string]int64{
- "device_nvme0_type_nvme_power_cycle_count": 2,
- "device_nvme0_type_nvme_power_on_time": 11206800,
- "device_nvme0_type_nvme_smart_status_failed": 0,
- "device_nvme0_type_nvme_smart_status_passed": 1,
- "device_nvme0_type_nvme_temperature": 39,
- },
- },
- "error on scan": {
- prepareMock: prepareMockErrOnScan,
- },
- "unexpected response on scan": {
- prepareMock: prepareMockUnexpectedResponse,
- },
- "empty response on scan": {
- prepareMock: prepareMockEmptyResponse,
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- smart := New()
- mock := test.prepareMock()
- smart.exec = mock
- smart.ScanEvery = web.Duration(time.Microsecond * 1)
- smart.PollDevicesEvery = web.Duration(time.Microsecond * 1)
-
- var mx map[string]int64
- for i := 0; i < 10; i++ {
- mx = smart.Collect()
- }
-
- assert.Equal(t, test.wantMetrics, mx)
- assert.Len(t, *smart.Charts(), test.wantCharts)
- testMetricsHasAllChartsDims(t, smart, mx)
- })
- }
-}
-
-func testMetricsHasAllChartsDims(t *testing.T, smart *Smartctl, mx map[string]int64) {
- for _, chart := range *smart.Charts() {
- if chart.Obsolete {
- continue
- }
- for _, dim := range chart.Dims {
- _, ok := mx[dim.ID]
- assert.Truef(t, ok, "collected metrics has no data for dim '%s' chart '%s'", dim.ID, chart.ID)
- }
- for _, v := range chart.Vars {
- _, ok := mx[v.ID]
- assert.Truef(t, ok, "collected metrics has no data for var '%s' chart '%s'", v.ID, chart.ID)
- }
- }
-}
-
-func prepareMockOkTypeSata() *mockSmartctlCliExec {
- return &mockSmartctlCliExec{
- errOnScan: false,
- scanData: dataTypeSataScan,
- deviceDataFunc: func(deviceName, deviceType, powerMode string) ([]byte, error) {
- if deviceType != "sat" {
- return nil, fmt.Errorf("unexpected device type %s", deviceType)
- }
- switch deviceName {
- case "/dev/sda":
- return dataTypeSataDeviceHDDSda, nil
- case "/dev/sdc":
- return dataTypeSataDeviceSSDSdc, nil
- default:
- return nil, fmt.Errorf("unexpected device name %s", deviceName)
- }
- },
- }
-}
-
-func prepareMockOkTypeNvme() *mockSmartctlCliExec {
- return &mockSmartctlCliExec{
- errOnScan: false,
- scanData: dataTypeNvmeScan,
- deviceDataFunc: func(deviceName, deviceType, powerMode string) ([]byte, error) {
- if deviceType != "nvme" {
- return nil, fmt.Errorf("unexpected device type %s", deviceType)
- }
- switch deviceName {
- case "/dev/nvme0":
- return dataTypeNvmeDeviceNvme0, nil
- default:
- return nil, fmt.Errorf("unexpected device name %s", deviceName)
- }
- },
- }
-}
-
-func prepareMockErrOnScan() *mockSmartctlCliExec {
- return &mockSmartctlCliExec{
- errOnScan: true,
- }
-}
-
-func prepareMockUnexpectedResponse() *mockSmartctlCliExec {
- return &mockSmartctlCliExec{
- scanData: []byte(randomJsonData),
- deviceDataFunc: func(_, _, _ string) ([]byte, error) { return []byte(randomJsonData), nil },
- }
-}
-
-func prepareMockEmptyResponse() *mockSmartctlCliExec {
- return &mockSmartctlCliExec{}
-}
-
-type mockSmartctlCliExec struct {
- errOnScan bool
- scanData []byte
- deviceDataFunc func(deviceName, deviceType, powerMode string) ([]byte, error)
-}
-
-func (m *mockSmartctlCliExec) scan() (*gjson.Result, error) {
- if m.errOnScan {
- return nil, fmt.Errorf("mock.scan() error")
- }
- res := gjson.ParseBytes(m.scanData)
- return &res, nil
-}
-
-func (m *mockSmartctlCliExec) deviceInfo(deviceName, deviceType, powerMode string) (*gjson.Result, error) {
- if m.deviceDataFunc == nil {
- return nil, nil
- }
- bs, err := m.deviceDataFunc(deviceName, deviceType, powerMode)
- if err != nil {
- return nil, err
- }
- res := gjson.ParseBytes(bs)
- return &res, nil
-}
-
-var randomJsonData = `
-{
- "elephant": {
- "burn": false,
- "mountain": true,
- "fog": false,
- "skin": -1561907625,
- "burst": "anyway",
- "shadow": 1558616893
- },
- "start": "ever",
- "base": 2093056027,
- "mission": -2007590351,
- "victory": 999053756,
- "die": false
-}
-`
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.json b/src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.json
deleted file mode 100644
index ed26105ee..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "update_every": 123,
- "timeout": 123.123,
- "scan_every": 123.123,
- "poll_devices_every": 123.123,
- "no_check_power_mode": "ok",
- "device_selector": "ok"
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.yaml b/src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.yaml
deleted file mode 100644
index 94c9b0acd..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/config.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-update_every: 123
-timeout: 123.123
-scan_every: 123.123
-poll_devices_every: 123.123
-no_check_power_mode: "ok"
-"device_selector": "ok"
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/device-nvme0.json b/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/device-nvme0.json
deleted file mode 100644
index 1b31d322d..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/device-nvme0.json
+++ /dev/null
@@ -1,112 +0,0 @@
-{
- "json_format_version": [
- 1,
- 0
- ],
- "smartctl": {
- "version": [
- 7,
- 3
- ],
- "svn_revision": "5338",
- "platform_info": "REDACTED",
- "build_info": "(local build)",
- "argv": [
- "smartctl",
- "--all",
- "--json",
- "--device=nvme",
- "/dev/nvme0"
- ],
- "exit_status": 0
- },
- "local_time": {
- "time_t": 1714480742,
- "asctime": "Tue Apr 30 15:39:02 2024 EEST"
- },
- "device": {
- "name": "/dev/nvme0",
- "info_name": "/dev/nvme0",
- "type": "nvme",
- "protocol": "NVMe"
- },
- "model_name": "Seagate FireCuda 530 ZP4000GM30023",
- "serial_number": "REDACTED",
- "firmware_version": "REDACTED",
- "nvme_pci_vendor": {
- "id": 7089,
- "subsystem_id": 7089
- },
- "nvme_ieee_oui_identifier": 6584743,
- "nvme_total_capacity": 4000787030016,
- "nvme_unallocated_capacity": 0,
- "nvme_controller_id": 1,
- "nvme_version": {
- "string": "1.4",
- "value": 66560
- },
- "nvme_number_of_namespaces": 1,
- "nvme_namespaces": [
- {
- "id": 1,
- "size": {
- "blocks": 7814037168,
- "bytes": 4000787030016
- },
- "capacity": {
- "blocks": 7814037168,
- "bytes": 4000787030016
- },
- "utilization": {
- "blocks": 7814037168,
- "bytes": 4000787030016
- },
- "formatted_lba_size": 512,
- "eui64": {
- "oui": 6584743,
- "ext_id": 553497146765
- }
- }
- ],
- "user_capacity": {
- "blocks": 7814037168,
- "bytes": 4000787030016
- },
- "logical_block_size": 512,
- "smart_support": {
- "available": true,
- "enabled": true
- },
- "smart_status": {
- "passed": true,
- "nvme": {
- "value": 0
- }
- },
- "nvme_smart_health_information_log": {
- "critical_warning": 0,
- "temperature": 39,
- "available_spare": 100,
- "available_spare_threshold": 5,
- "percentage_used": 0,
- "data_units_read": 52,
- "data_units_written": 0,
- "host_reads": 550,
- "host_writes": 0,
- "controller_busy_time": 0,
- "power_cycles": 2,
- "power_on_hours": 3113,
- "unsafe_shutdowns": 1,
- "media_errors": 0,
- "num_err_log_entries": 4,
- "warning_temp_time": 0,
- "critical_comp_time": 0
- },
- "temperature": {
- "current": 39
- },
- "power_cycle_count": 2,
- "power_on_time": {
- "hours": 3113
- }
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/scan.json b/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/scan.json
deleted file mode 100644
index b9f716cbd..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-nvme/scan.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "json_format_version": [
- 1,
- 0
- ],
- "smartctl": {
- "version": [
- 7,
- 3
- ],
- "svn_revision": "5338",
- "platform_info": "REDACTED",
- "build_info": "(local build)",
- "argv": [
- "smartctl",
- "--scan",
- "--json"
- ],
- "exit_status": 0
- },
- "devices": [
- {
- "name": "/dev/nvme0",
- "info_name": "/dev/nvme0",
- "type": "nvme",
- "protocol": "NVMe"
- }
- ]
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-hdd-sda.json b/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-hdd-sda.json
deleted file mode 100644
index 55cfe15f5..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-hdd-sda.json
+++ /dev/null
@@ -1,601 +0,0 @@
-{
- "json_format_version": [
- 1,
- 0
- ],
- "smartctl": {
- "version": [
- 7,
- 3
- ],
- "svn_revision": "5338",
- "platform_info": "REDACTED",
- "build_info": "(local build)",
- "argv": [
- "smartctl",
- "--all",
- "--json",
- "--device=sat",
- "/dev/sda"
- ],
- "drive_database_version": {
- "string": "7.3/5319"
- },
- "exit_status": 0
- },
- "local_time": {
- "time_t": 1714480013,
- "asctime": "Tue Apr 30 15:26:53 2024 EEST"
- },
- "device": {
- "name": "/dev/sda",
- "info_name": "/dev/sda [SAT]",
- "type": "sat",
- "protocol": "ATA"
- },
- "model_name": "WDC WD181KRYZ-01AGBB0",
- "serial_number": "REDACTED",
- "wwn": {
- "naa": 5,
- "oui": 3274,
- "id": 11659362274
- },
- "firmware_version": "REDACTED",
- "user_capacity": {
- "blocks": 35156656128,
- "bytes": 18000207937536
- },
- "logical_block_size": 512,
- "physical_block_size": 4096,
- "rotation_rate": 7200,
- "form_factor": {
- "ata_value": 2,
- "name": "3.5 inches"
- },
- "trim": {
- "supported": false
- },
- "in_smartctl_database": false,
- "ata_version": {
- "string": "ACS-4 published, ANSI INCITS 529-2018",
- "major_value": 4092,
- "minor_value": 156
- },
- "sata_version": {
- "string": "SATA 3.3",
- "value": 511
- },
- "interface_speed": {
- "max": {
- "sata_value": 14,
- "string": "6.0 Gb/s",
- "units_per_second": 60,
- "bits_per_unit": 100000000
- },
- "current": {
- "sata_value": 3,
- "string": "6.0 Gb/s",
- "units_per_second": 60,
- "bits_per_unit": 100000000
- }
- },
- "smart_support": {
- "available": true,
- "enabled": true
- },
- "smart_status": {
- "passed": true
- },
- "ata_smart_data": {
- "offline_data_collection": {
- "status": {
- "value": 130,
- "string": "was completed without error",
- "passed": true
- },
- "completion_seconds": 101
- },
- "self_test": {
- "status": {
- "value": 0,
- "string": "completed without error",
- "passed": true
- },
- "polling_minutes": {
- "short": 2,
- "extended": 1883
- }
- },
- "capabilities": {
- "values": [
- 91,
- 3
- ],
- "exec_offline_immediate_supported": true,
- "offline_is_aborted_upon_new_cmd": false,
- "offline_surface_scan_supported": true,
- "self_tests_supported": true,
- "conveyance_self_test_supported": false,
- "selective_self_test_supported": true,
- "attribute_autosave_enabled": true,
- "error_logging_supported": true,
- "gp_logging_supported": true
- }
- },
- "ata_sct_capabilities": {
- "value": 61,
- "error_recovery_control_supported": true,
- "feature_control_supported": true,
- "data_table_supported": true
- },
- "ata_smart_attributes": {
- "revision": 16,
- "table": [
- {
- "id": 1,
- "name": "Raw_Read_Error_Rate",
- "value": 100,
- "worst": 100,
- "thresh": 1,
- "when_failed": "",
- "flags": {
- "value": 11,
- "string": "PO-R-- ",
- "prefailure": true,
- "updated_online": true,
- "performance": false,
- "error_rate": true,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 2,
- "name": "Throughput_Performance",
- "value": 148,
- "worst": 148,
- "thresh": 54,
- "when_failed": "",
- "flags": {
- "value": 5,
- "string": "P-S--- ",
- "prefailure": true,
- "updated_online": false,
- "performance": true,
- "error_rate": false,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 48,
- "string": "48"
- }
- },
- {
- "id": 3,
- "name": "Spin_Up_Time",
- "value": 86,
- "worst": 86,
- "thresh": 1,
- "when_failed": "",
- "flags": {
- "value": 7,
- "string": "POS--- ",
- "prefailure": true,
- "updated_online": true,
- "performance": true,
- "error_rate": false,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 25788088601,
- "string": "281 (Average 279)"
- }
- },
- {
- "id": 4,
- "name": "Start_Stop_Count",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 18,
- "string": "-O--C- ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": false
- },
- "raw": {
- "value": 12,
- "string": "12"
- }
- },
- {
- "id": 5,
- "name": "Reallocated_Sector_Ct",
- "value": 100,
- "worst": 100,
- "thresh": 1,
- "when_failed": "",
- "flags": {
- "value": 51,
- "string": "PO--CK ",
- "prefailure": true,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 7,
- "name": "Seek_Error_Rate",
- "value": 100,
- "worst": 100,
- "thresh": 1,
- "when_failed": "",
- "flags": {
- "value": 11,
- "string": "PO-R-- ",
- "prefailure": true,
- "updated_online": true,
- "performance": false,
- "error_rate": true,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 8,
- "name": "Seek_Time_Performance",
- "value": 140,
- "worst": 140,
- "thresh": 20,
- "when_failed": "",
- "flags": {
- "value": 5,
- "string": "P-S--- ",
- "prefailure": true,
- "updated_online": false,
- "performance": true,
- "error_rate": false,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 15,
- "string": "15"
- }
- },
- {
- "id": 9,
- "name": "Power_On_Hours",
- "value": 99,
- "worst": 99,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 18,
- "string": "-O--C- ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": false
- },
- "raw": {
- "value": 8244,
- "string": "8244"
- }
- },
- {
- "id": 10,
- "name": "Spin_Retry_Count",
- "value": 100,
- "worst": 100,
- "thresh": 1,
- "when_failed": "",
- "flags": {
- "value": 19,
- "string": "PO--C- ",
- "prefailure": true,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": false
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 12,
- "name": "Power_Cycle_Count",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 12,
- "string": "12"
- }
- },
- {
- "id": 22,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "thresh": 25,
- "when_failed": "",
- "flags": {
- "value": 35,
- "string": "PO---K ",
- "prefailure": true,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": false,
- "auto_keep": true
- },
- "raw": {
- "value": 100,
- "string": "100"
- }
- },
- {
- "id": 192,
- "name": "Power-Off_Retract_Count",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 360,
- "string": "360"
- }
- },
- {
- "id": 193,
- "name": "Load_Cycle_Count",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 18,
- "string": "-O--C- ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": false
- },
- "raw": {
- "value": 360,
- "string": "360"
- }
- },
- {
- "id": 194,
- "name": "Temperature_Celsius",
- "value": 43,
- "worst": 43,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 2,
- "string": "-O---- ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 240519741489,
- "string": "49 (Min/Max 24/56)"
- }
- },
- {
- "id": 196,
- "name": "Reallocated_Event_Count",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 197,
- "name": "Current_Pending_Sector",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 34,
- "string": "-O---K ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": false,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 198,
- "name": "Offline_Uncorrectable",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 8,
- "string": "---R-- ",
- "prefailure": false,
- "updated_online": false,
- "performance": false,
- "error_rate": true,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 199,
- "name": "UDMA_CRC_Error_Count",
- "value": 100,
- "worst": 100,
- "thresh": 0,
- "when_failed": "",
- "flags": {
- "value": 10,
- "string": "-O-R-- ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": true,
- "event_count": false,
- "auto_keep": false
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- }
- ]
- },
- "power_on_time": {
- "hours": 8244
- },
- "power_cycle_count": 12,
- "temperature": {
- "current": 49
- },
- "ata_smart_error_log": {
- "summary": {
- "revision": 1,
- "count": 0
- }
- },
- "ata_smart_self_test_log": {
- "standard": {
- "revision": 1,
- "count": 0
- }
- },
- "ata_smart_selective_self_test_log": {
- "revision": 1,
- "table": [
- {
- "lba_min": 0,
- "lba_max": 0,
- "status": {
- "value": 0,
- "string": "Not_testing"
- }
- },
- {
- "lba_min": 0,
- "lba_max": 0,
- "status": {
- "value": 0,
- "string": "Not_testing"
- }
- },
- {
- "lba_min": 0,
- "lba_max": 0,
- "status": {
- "value": 0,
- "string": "Not_testing"
- }
- },
- {
- "lba_min": 0,
- "lba_max": 0,
- "status": {
- "value": 0,
- "string": "Not_testing"
- }
- },
- {
- "lba_min": 0,
- "lba_max": 0,
- "status": {
- "value": 0,
- "string": "Not_testing"
- }
- }
- ],
- "flags": {
- "value": 0,
- "remainder_scan_enabled": false
- },
- "power_up_scan_resume_minutes": 0
- }
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-ssd-sdc.json b/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-ssd-sdc.json
deleted file mode 100644
index a2d8f0aaf..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/device-ssd-sdc.json
+++ /dev/null
@@ -1,652 +0,0 @@
-{
- "json_format_version": [
- 1,
- 0
- ],
- "smartctl": {
- "version": [
- 7,
- 3
- ],
- "svn_revision": "5338",
- "platform_info": "REDACTED",
- "build_info": "(local build)",
- "argv": [
- "smartctl",
- "--all",
- "--json",
- "--device=sat",
- "/dev/sdc"
- ],
- "drive_database_version": {
- "string": "7.3/5319"
- },
- "exit_status": 0
- },
- "local_time": {
- "time_t": 1714480059,
- "asctime": "Tue Apr 30 15:27:39 2024 EEST"
- },
- "device": {
- "name": "/dev/sdc",
- "info_name": "/dev/sdc [SAT]",
- "type": "sat",
- "protocol": "ATA"
- },
- "model_name": "WDC WDS400T1R0A-68A4W0",
- "serial_number": "REDACTED",
- "wwn": {
- "naa": 5,
- "oui": 6980,
- "id": 37319905210
- },
- "firmware_version": "REDACTED",
- "user_capacity": {
- "blocks": 7814037168,
- "bytes": 4000787030016
- },
- "logical_block_size": 512,
- "physical_block_size": 512,
- "rotation_rate": 0,
- "form_factor": {
- "ata_value": 3,
- "name": "2.5 inches"
- },
- "trim": {
- "supported": true,
- "deterministic": true,
- "zeroed": true
- },
- "in_smartctl_database": false,
- "ata_version": {
- "string": "ACS-4 T13/BSR INCITS 529 revision 5",
- "major_value": 4080,
- "minor_value": 94
- },
- "sata_version": {
- "string": "SATA 3.3",
- "value": 511
- },
- "interface_speed": {
- "max": {
- "sata_value": 14,
- "string": "6.0 Gb/s",
- "units_per_second": 60,
- "bits_per_unit": 100000000
- },
- "current": {
- "sata_value": 3,
- "string": "6.0 Gb/s",
- "units_per_second": 60,
- "bits_per_unit": 100000000
- }
- },
- "smart_support": {
- "available": true,
- "enabled": true
- },
- "smart_status": {
- "passed": true
- },
- "ata_smart_data": {
- "offline_data_collection": {
- "status": {
- "value": 0,
- "string": "was never started"
- },
- "completion_seconds": 0
- },
- "self_test": {
- "status": {
- "value": 0,
- "string": "completed without error",
- "passed": true
- },
- "polling_minutes": {
- "short": 2,
- "extended": 10
- }
- },
- "capabilities": {
- "values": [
- 17,
- 3
- ],
- "exec_offline_immediate_supported": true,
- "offline_is_aborted_upon_new_cmd": false,
- "offline_surface_scan_supported": false,
- "self_tests_supported": true,
- "conveyance_self_test_supported": false,
- "selective_self_test_supported": false,
- "attribute_autosave_enabled": true,
- "error_logging_supported": true,
- "gp_logging_supported": true
- }
- },
- "ata_smart_attributes": {
- "revision": 4,
- "table": [
- {
- "id": 5,
- "name": "Reallocated_Sector_Ct",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 9,
- "name": "Power_On_Hours",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 8244,
- "string": "8244"
- }
- },
- {
- "id": 12,
- "name": "Power_Cycle_Count",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 13,
- "string": "13"
- }
- },
- {
- "id": 165,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 515627355118,
- "string": "515627355118"
- }
- },
- {
- "id": 166,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 1,
- "string": "1"
- }
- },
- {
- "id": 167,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 84,
- "string": "84"
- }
- },
- {
- "id": 168,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 34,
- "string": "34"
- }
- },
- {
- "id": 169,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 1600,
- "string": "1600"
- }
- },
- {
- "id": 170,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 171,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 172,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 173,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 15,
- "string": "15"
- }
- },
- {
- "id": 174,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 4,
- "string": "4"
- }
- },
- {
- "id": 184,
- "name": "End-to-End_Error",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 187,
- "name": "Reported_Uncorrect",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 188,
- "name": "Command_Timeout",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 194,
- "name": "Temperature_Celsius",
- "value": 73,
- "worst": 43,
- "flags": {
- "value": 34,
- "string": "-O---K ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": false,
- "auto_keep": true
- },
- "raw": {
- "value": 184684970011,
- "string": "27 (Min/Max 21/43)"
- }
- },
- {
- "id": 199,
- "name": "UDMA_CRC_Error_Count",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- },
- {
- "id": 230,
- "name": "Unknown_SSD_Attribute",
- "value": 4,
- "worst": 4,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 4694419309637,
- "string": "4694419309637"
- }
- },
- {
- "id": 232,
- "name": "Available_Reservd_Space",
- "value": 100,
- "worst": 100,
- "thresh": 4,
- "when_failed": "",
- "flags": {
- "value": 51,
- "string": "PO--CK ",
- "prefailure": true,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 100,
- "string": "100"
- }
- },
- {
- "id": 233,
- "name": "Media_Wearout_Indicator",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 65406,
- "string": "65406"
- }
- },
- {
- "id": 234,
- "name": "Unknown_Attribute",
- "value": 100,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 190852,
- "string": "190852"
- }
- },
- {
- "id": 241,
- "name": "Total_LBAs_Written",
- "value": 253,
- "worst": 253,
- "flags": {
- "value": 48,
- "string": "----CK ",
- "prefailure": false,
- "updated_online": false,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 173833,
- "string": "173833"
- }
- },
- {
- "id": 242,
- "name": "Total_LBAs_Read",
- "value": 253,
- "worst": 253,
- "flags": {
- "value": 48,
- "string": "----CK ",
- "prefailure": false,
- "updated_online": false,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 76778,
- "string": "76778"
- }
- },
- {
- "id": 244,
- "name": "Unknown_Attribute",
- "value": 0,
- "worst": 100,
- "flags": {
- "value": 50,
- "string": "-O--CK ",
- "prefailure": false,
- "updated_online": true,
- "performance": false,
- "error_rate": false,
- "event_count": true,
- "auto_keep": true
- },
- "raw": {
- "value": 0,
- "string": "0"
- }
- }
- ]
- },
- "power_on_time": {
- "hours": 8244
- },
- "power_cycle_count": 13,
- "temperature": {
- "current": 27
- },
- "ata_smart_error_log": {
- "summary": {
- "revision": 1,
- "count": 0
- }
- },
- "ata_smart_self_test_log": {
- "standard": {
- "revision": 1,
- "count": 0
- }
- }
-}
diff --git a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/scan.json b/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/scan.json
deleted file mode 100644
index c7a68ca8d..000000000
--- a/src/go/collectors/go.d.plugin/modules/smartctl/testdata/type-sat/scan.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "json_format_version": [
- 1,
- 0
- ],
- "smartctl": {
- "version": [
- 7,
- 3
- ],
- "svn_revision": "5338",
- "platform_info": "REDACTED",
- "build_info": "(local build)",
- "argv": [
- "smartctl",
- "--scan",
- "--json"
- ],
- "exit_status": 0
- },
- "devices": [
- {
- "name": "/dev/sda",
- "info_name": "/dev/sda [SAT]",
- "type": "sat",
- "protocol": "ATA"
- },
- {
- "name": "/dev/sdc",
- "info_name": "/dev/sdc [SAT]",
- "type": "sat",
- "protocol": "ATA"
- }
- ]
-}