mirror of
https://github.com/ClusterCockpit/cc-metric-collector.git
synced 2026-03-10 10:37:29 +01:00
* Honor config option excluded devices
* Use device type in read command
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
cclog "github.com/ClusterCockpit/cc-lib/v2/ccLogger"
|
cclog "github.com/ClusterCockpit/cc-lib/v2/ccLogger"
|
||||||
@@ -15,24 +16,25 @@ type SmartMonCollectorConfig struct {
|
|||||||
ExcludeDevices []string `json:"exclude_devices,omitempty"`
|
ExcludeDevices []string `json:"exclude_devices,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type deviceT struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
type SmartMonCollector struct {
|
type SmartMonCollector struct {
|
||||||
metricCollector
|
metricCollector
|
||||||
config SmartMonCollectorConfig // the configuration structure
|
config SmartMonCollectorConfig // the configuration structure
|
||||||
meta map[string]string // default meta information
|
meta map[string]string // default meta information
|
||||||
tags map[string]string // default tags
|
tags map[string]string // default tags
|
||||||
devices []string // smartmon devices
|
devices []deviceT // smartmon devices
|
||||||
sudoCmd string // Full path to 'sudo' command
|
sudoCmd string // Full path to 'sudo' command
|
||||||
smartCtlCmd string // Full path to 'smartctl' command
|
smartCtlCmd string // Full path to 'smartctl' command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SmartMonCollector) getSmartmonDevices() error {
|
func (m *SmartMonCollector) getSmartmonDevices() error {
|
||||||
var scan struct {
|
var scan struct {
|
||||||
Devices []struct {
|
Devices []deviceT `json:"devices"`
|
||||||
Name string `json:"name"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
} `json:"devices"`
|
|
||||||
}
|
}
|
||||||
m.devices = make([]string, 0)
|
|
||||||
|
|
||||||
var command *exec.Cmd
|
var command *exec.Cmd
|
||||||
if m.config.UseSudo {
|
if m.config.UseSudo {
|
||||||
@@ -52,9 +54,11 @@ func (m *SmartMonCollector) getSmartmonDevices() error {
|
|||||||
return fmt.Errorf("%s getSmartmonDevices(): Failed to parse JSON output from device scan command: %w",
|
return fmt.Errorf("%s getSmartmonDevices(): Failed to parse JSON output from device scan command: %w",
|
||||||
m.name, err)
|
m.name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.devices = make([]deviceT, 0)
|
||||||
for _, d := range scan.Devices {
|
for _, d := range scan.Devices {
|
||||||
if len(d.Name) > 0 {
|
if !slices.Contains(m.config.ExcludeDevices, d.Name) {
|
||||||
m.devices = append(m.devices, d.Name)
|
m.devices = append(m.devices, d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,107 +139,107 @@ func (m *SmartMonCollector) Read(interval time.Duration, output chan lp.CCMessag
|
|||||||
var command *exec.Cmd
|
var command *exec.Cmd
|
||||||
var data SmartMonData
|
var data SmartMonData
|
||||||
if m.config.UseSudo {
|
if m.config.UseSudo {
|
||||||
command = exec.Command(m.sudoCmd, m.smartCtlCmd, "-j", "-a", d)
|
command = exec.Command(m.sudoCmd, m.smartCtlCmd, "--json=c", "--device="+d.Type, "--all", d.Name)
|
||||||
} else {
|
} else {
|
||||||
command = exec.Command(m.smartCtlCmd, "-j", "-a", d)
|
command = exec.Command(m.smartCtlCmd, "--json=c", "--device="+d.Type, "--all", d.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, err := command.Output()
|
stdout, err := command.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cclog.ComponentError(m.name, "cannot read data for device", d)
|
cclog.ComponentError(m.name, "cannot read data for device", d.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = json.Unmarshal(stdout, &data)
|
err = json.Unmarshal(stdout, &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cclog.ComponentError(m.name, "cannot unmarshal data for device", d)
|
cclog.ComponentError(m.name, "cannot unmarshal data for device", d.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y, err := lp.NewMetric(
|
y, err := lp.NewMetric(
|
||||||
"smartmon_temp", m.tags, m.meta, data.HealthLog.Temperature, timestamp)
|
"smartmon_temp", m.tags, m.meta, data.HealthLog.Temperature, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
y.AddMeta("unit", "degC")
|
y.AddMeta("unit", "degC")
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_percent_used", m.tags, m.meta, data.HealthLog.PercentageUsed, timestamp)
|
"smartmon_percent_used", m.tags, m.meta, data.HealthLog.PercentageUsed, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
y.AddMeta("unit", "percent")
|
y.AddMeta("unit", "percent")
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_avail_spare", m.tags, m.meta, data.HealthLog.AvailableSpare, timestamp)
|
"smartmon_avail_spare", m.tags, m.meta, data.HealthLog.AvailableSpare, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
y.AddMeta("unit", "percent")
|
y.AddMeta("unit", "percent")
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_data_units_read", m.tags, m.meta, data.HealthLog.DataUnitsRead, timestamp)
|
"smartmon_data_units_read", m.tags, m.meta, data.HealthLog.DataUnitsRead, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_data_units_write", m.tags, m.meta, data.HealthLog.DataUnitsWrite, timestamp)
|
"smartmon_data_units_write", m.tags, m.meta, data.HealthLog.DataUnitsWrite, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_host_reads", m.tags, m.meta, data.HealthLog.HostReads, timestamp)
|
"smartmon_host_reads", m.tags, m.meta, data.HealthLog.HostReads, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_host_writes", m.tags, m.meta, data.HealthLog.HostWrites, timestamp)
|
"smartmon_host_writes", m.tags, m.meta, data.HealthLog.HostWrites, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_power_cycles", m.tags, m.meta, data.HealthLog.PowerCycles, timestamp)
|
"smartmon_power_cycles", m.tags, m.meta, data.HealthLog.PowerCycles, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_power_on", m.tags, m.meta, int64(data.HealthLog.PowerOnHours)*3600, timestamp)
|
"smartmon_power_on", m.tags, m.meta, int64(data.HealthLog.PowerOnHours)*3600, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
y.AddMeta("unit", "sec")
|
y.AddMeta("unit", "sec")
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_unsafe_shutdowns", m.tags, m.meta, data.HealthLog.UnsafeShutdowns, timestamp)
|
"smartmon_unsafe_shutdowns", m.tags, m.meta, data.HealthLog.UnsafeShutdowns, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_media_errors", m.tags, m.meta, data.HealthLog.MediaErrors, timestamp)
|
"smartmon_media_errors", m.tags, m.meta, data.HealthLog.MediaErrors, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_errlog_entries", m.tags, m.meta, data.HealthLog.NumErrorLogEntries, timestamp)
|
"smartmon_errlog_entries", m.tags, m.meta, data.HealthLog.NumErrorLogEntries, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_warn_temp_time", m.tags, m.meta, data.HealthLog.WarnTempTime, timestamp)
|
"smartmon_warn_temp_time", m.tags, m.meta, data.HealthLog.WarnTempTime, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
y, err = lp.NewMetric(
|
y, err = lp.NewMetric(
|
||||||
"smartmon_crit_temp_time", m.tags, m.meta, data.HealthLog.CriticalTempTime, timestamp)
|
"smartmon_crit_temp_time", m.tags, m.meta, data.HealthLog.CriticalTempTime, timestamp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddTag("stype-id", d)
|
y.AddTag("stype-id", d.Name)
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user