summaryrefslogtreecommitdiffstats
path: root/src/go/plugin/go.d/modules/adaptecraid/collect_pd.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/go/plugin/go.d/modules/adaptecraid/collect_pd.go128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/go/plugin/go.d/modules/adaptecraid/collect_pd.go b/src/go/plugin/go.d/modules/adaptecraid/collect_pd.go
new file mode 100644
index 000000000..272266b47
--- /dev/null
+++ b/src/go/plugin/go.d/modules/adaptecraid/collect_pd.go
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package adaptecraid
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+type physicalDevice struct {
+ number string
+ state string
+ location string
+ vendor string
+ model string
+ smart string
+ smartWarnings string
+ powerState string
+ temperature string
+}
+
+func (a *AdaptecRaid) collectPhysicalDevices(mx map[string]int64) error {
+ bs, err := a.exec.physicalDevicesInfo()
+ if err != nil {
+ return err
+ }
+
+ devices, err := parsePhysDevInfo(bs)
+ if err != nil {
+ return err
+ }
+
+ if len(devices) == 0 {
+ return errors.New("no physical devices found")
+ }
+
+ for _, pd := range devices {
+ if !a.pds[pd.number] {
+ a.pds[pd.number] = true
+ a.addPhysicalDeviceCharts(pd)
+ }
+
+ px := fmt.Sprintf("pd_%s_", pd.number)
+
+ // Unfortunately, all available states are unknown.
+ mx[px+"health_state_ok"] = 0
+ mx[px+"health_state_critical"] = 0
+ if isOkPDState(pd) {
+ mx[px+"health_state_ok"] = 1
+ } else {
+ mx[px+"health_state_critical"] = 1
+ }
+
+ if v, err := strconv.ParseInt(pd.smartWarnings, 10, 64); err == nil {
+ mx[px+"smart_warnings"] = v
+ }
+ if v, err := strconv.ParseInt(pd.temperature, 10, 64); err == nil {
+ mx[px+"temperature"] = v
+ }
+ }
+
+ return nil
+}
+
+func isOkPDState(pd *physicalDevice) bool {
+ // https://github.com/thomas-krenn/check_adaptec_raid/blob/a104fd88deede87df4f07403b44394bffb30c5c3/check_adaptec_raid#L455
+ switch pd.state {
+ case "Online",
+ "Global Hot-Spare",
+ "Dedicated Hot-Spare",
+ "Pooled Hot-Spare",
+ "Hot Spare",
+ "Ready",
+ "Online (JBOD)",
+ "Raw (Pass Through)":
+ return true
+ }
+ return false
+}
+
+func parsePhysDevInfo(bs []byte) (map[string]*physicalDevice, error) {
+ devices := make(map[string]*physicalDevice)
+
+ var pd *physicalDevice
+
+ sc := bufio.NewScanner(bytes.NewReader(bs))
+
+ for sc.Scan() {
+ line := strings.TrimSpace(sc.Text())
+
+ if strings.HasPrefix(line, "Device #") {
+ num := strings.TrimPrefix(line, "Device #")
+ pd = &physicalDevice{number: num}
+ devices[num] = pd
+ continue
+ }
+
+ if pd == nil {
+ continue
+ }
+
+ switch {
+ case strings.HasPrefix(line, "State"):
+ pd.state = getColonSepValue(line)
+ case strings.HasPrefix(line, "Reported Location"):
+ pd.location = getColonSepValue(line)
+ case strings.HasPrefix(line, "Vendor"):
+ pd.vendor = getColonSepValue(line)
+ case strings.HasPrefix(line, "Model"):
+ pd.model = getColonSepValue(line)
+ case strings.HasPrefix(line, "S.M.A.R.T. warnings"):
+ pd.smartWarnings = getColonSepValue(line)
+ case strings.HasPrefix(line, "S.M.A.R.T."):
+ pd.smart = getColonSepValue(line)
+ case strings.HasPrefix(line, "Power State"):
+ pd.powerState = getColonSepValue(line)
+ case strings.HasPrefix(line, "Temperature"):
+ v := getColonSepValue(line) // '42 C/ 107 F' or 'Not Supported'
+ pd.temperature = strings.Fields(v)[0]
+ }
+ }
+
+ return devices, nil
+}