Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
196
plugins/inputs/smartctl/smartctl_device.go
Normal file
196
plugins/inputs/smartctl/smartctl_device.go
Normal file
|
@ -0,0 +1,196 @@
|
|||
package smartctl
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
)
|
||||
|
||||
func (s *Smartctl) scanDevice(acc telegraf.Accumulator, deviceName, deviceType string) error {
|
||||
args := []string{"--json", "--all", deviceName, "--device", deviceType, "--nocheck=" + s.NoCheck}
|
||||
cmd := execCommand(s.Path, args...)
|
||||
if s.UseSudo {
|
||||
cmd = execCommand("sudo", append([]string{"-n", s.Path}, args...)...)
|
||||
}
|
||||
|
||||
var device smartctlDeviceJSON
|
||||
out, err := internal.CombinedOutputTimeout(cmd, time.Duration(s.Timeout))
|
||||
if err != nil {
|
||||
// Error running the command and unable to parse the JSON, then bail
|
||||
if jsonErr := json.Unmarshal(out, &device); jsonErr != nil {
|
||||
return fmt.Errorf("error running smartctl with %s: %w", args, err)
|
||||
}
|
||||
|
||||
// If we were able to parse the result, then only exit if we get an error
|
||||
// as sometimes we can get warnings, that still produce data.
|
||||
if len(device.Smartctl.Messages) > 0 &&
|
||||
device.Smartctl.Messages[0].Severity == "error" &&
|
||||
device.Smartctl.Messages[0].String != "" {
|
||||
return fmt.Errorf("error running smartctl with %s got smartctl error message: %s", args, device.Smartctl.Messages[0].String)
|
||||
}
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(out, &device); err != nil {
|
||||
return fmt.Errorf("error unable to unmarshall response %s: %w", args, err)
|
||||
}
|
||||
|
||||
t := time.Now()
|
||||
|
||||
tags := map[string]string{
|
||||
"name": device.Device.Name,
|
||||
"type": device.Device.Type,
|
||||
"serial": device.SerialNumber,
|
||||
}
|
||||
|
||||
if device.ModelName != "" {
|
||||
tags["model"] = device.ModelName
|
||||
}
|
||||
if device.Vendor != "" {
|
||||
tags["vendor"] = device.Vendor
|
||||
}
|
||||
|
||||
// The JSON WWN is in decimal and needs to be converted to hex
|
||||
if device.Wwn.ID != 0 && device.Wwn.Naa != 0 && device.Wwn.Oui != 0 {
|
||||
tags["wwn"] = fmt.Sprintf("%01x%06x%09x", device.Wwn.Naa, device.Wwn.Oui, device.Wwn.ID)
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"capacity": device.UserCapacity.Bytes,
|
||||
"health_ok": device.SmartStatus.Passed,
|
||||
"temperature": device.Temperature.Current,
|
||||
"firmware": device.FirmwareVersion,
|
||||
}
|
||||
|
||||
if device.SCSIVendor != "" {
|
||||
fields["scsi_vendor"] = device.SCSIVendor
|
||||
}
|
||||
if device.SCSIModelName != "" {
|
||||
fields["scsi_model"] = device.SCSIModelName
|
||||
}
|
||||
if device.SCSIRevision != "" {
|
||||
fields["scsi_revision"] = device.SCSIRevision
|
||||
}
|
||||
if device.SCSIVersion != "" {
|
||||
fields["scsi_version"] = device.SCSIVersion
|
||||
}
|
||||
if device.SCSITransportProtocol.Name != "" {
|
||||
fields["scsi_transport_protocol"] = device.SCSITransportProtocol.Name
|
||||
}
|
||||
if device.SCSIProtectionType != 0 {
|
||||
fields["scsi_protection_type"] = device.SCSIProtectionType
|
||||
}
|
||||
if device.SCSIProtectionIntervalBytesPerLB != 0 {
|
||||
fields["scsi_protection_interval_bytes_per_lb"] = device.SCSIProtectionIntervalBytesPerLB
|
||||
}
|
||||
if device.SCSIGrownDefectList != 0 {
|
||||
fields["scsi_grown_defect_list"] = device.SCSIGrownDefectList
|
||||
}
|
||||
if device.LogicalBlockSize != 0 {
|
||||
fields["logical_block_size"] = device.LogicalBlockSize
|
||||
}
|
||||
if device.RotationRate != 0 {
|
||||
fields["rotation_rate"] = device.RotationRate
|
||||
}
|
||||
if device.SCSIStartStopCycleCounter.SpecifiedCycleCountOverDeviceLifetime != 0 {
|
||||
fields["specified_cycle_count_over_device_lifetime"] = device.SCSIStartStopCycleCounter.SpecifiedCycleCountOverDeviceLifetime
|
||||
}
|
||||
if device.SCSIStartStopCycleCounter.AccumulatedStartStopCycles != 0 {
|
||||
fields["accumulated_start_stop_cycles"] = device.SCSIStartStopCycleCounter.AccumulatedStartStopCycles
|
||||
}
|
||||
if device.PowerOnTime.Hours != 0 {
|
||||
fields["power_on_hours"] = device.PowerOnTime.Hours
|
||||
}
|
||||
if device.PowerOnTime.Minutes != 0 {
|
||||
fields["power_on_minutes"] = device.PowerOnTime.Minutes
|
||||
}
|
||||
|
||||
// Add NVMe specific fields
|
||||
if device.Device.Type == "nvme" {
|
||||
fields["critical_warning"] = device.NvmeSmartHealthInformationLog.CriticalWarning
|
||||
fields["temperature"] = device.NvmeSmartHealthInformationLog.Temperature
|
||||
fields["available_spare"] = device.NvmeSmartHealthInformationLog.AvailableSpare
|
||||
fields["available_spare_threshold"] = device.NvmeSmartHealthInformationLog.AvailableSpareThreshold
|
||||
fields["percentage_used"] = device.NvmeSmartHealthInformationLog.PercentageUsed
|
||||
fields["data_units_read"] = device.NvmeSmartHealthInformationLog.DataUnitsRead
|
||||
fields["data_units_written"] = device.NvmeSmartHealthInformationLog.DataUnitsWritten
|
||||
fields["host_reads"] = device.NvmeSmartHealthInformationLog.HostReads
|
||||
fields["host_writes"] = device.NvmeSmartHealthInformationLog.HostWrites
|
||||
fields["controller_busy_time"] = device.NvmeSmartHealthInformationLog.ControllerBusyTime
|
||||
fields["power_cycles"] = device.NvmeSmartHealthInformationLog.PowerCycles
|
||||
fields["power_on_hours"] = device.NvmeSmartHealthInformationLog.PowerOnHours
|
||||
fields["unsafe_shutdowns"] = device.NvmeSmartHealthInformationLog.UnsafeShutdowns
|
||||
fields["media_errors"] = device.NvmeSmartHealthInformationLog.MediaErrors
|
||||
fields["num_err_log_entries"] = device.NvmeSmartHealthInformationLog.NumErrLogEntries
|
||||
fields["warning_temp_time"] = device.NvmeSmartHealthInformationLog.WarningTempTime
|
||||
fields["critical_comp_time"] = device.NvmeSmartHealthInformationLog.CriticalCompTime
|
||||
}
|
||||
|
||||
acc.AddFields("smartctl", fields, tags, t)
|
||||
|
||||
// Check for ATA specific attribute fields
|
||||
for _, attribute := range device.AtaSmartAttributes.Table {
|
||||
attributeTags := make(map[string]string, len(tags)+1)
|
||||
for k, v := range tags {
|
||||
attributeTags[k] = v
|
||||
}
|
||||
attributeTags["name"] = attribute.Name
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"raw_value": attribute.Raw.Value,
|
||||
"worst": attribute.Worst,
|
||||
"threshold": attribute.Thresh,
|
||||
"value": attribute.Value,
|
||||
}
|
||||
|
||||
acc.AddFields("smartctl_attributes", fields, attributeTags, t)
|
||||
}
|
||||
|
||||
// Check for SCSI error counter entries
|
||||
if device.Device.Type == "scsi" {
|
||||
counterTags := make(map[string]string, len(tags)+1)
|
||||
for k, v := range tags {
|
||||
counterTags[k] = v
|
||||
}
|
||||
|
||||
counterTags["page"] = "read"
|
||||
fields := map[string]interface{}{
|
||||
"errors_corrected_by_eccfast": device.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccfast,
|
||||
"errors_corrected_by_eccdelayed": device.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccdelayed,
|
||||
"errors_corrected_by_rereads_rewrites": device.ScsiErrorCounterLog.Read.ErrorsCorrectedByRereadsRewrites,
|
||||
"total_errors_corrected": device.ScsiErrorCounterLog.Read.TotalErrorsCorrected,
|
||||
"correction_algorithm_invocations": device.ScsiErrorCounterLog.Read.CorrectionAlgorithmInvocations,
|
||||
"gigabytes_processed": device.ScsiErrorCounterLog.Read.GigabytesProcessed,
|
||||
"total_uncorrected_errors": device.ScsiErrorCounterLog.Read.TotalUncorrectedErrors,
|
||||
}
|
||||
acc.AddFields("smartctl_scsi_error_counter_log", fields, counterTags, t)
|
||||
|
||||
counterTags["page"] = "write"
|
||||
fields = map[string]interface{}{
|
||||
"errors_corrected_by_eccfast": device.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccfast,
|
||||
"errors_corrected_by_eccdelayed": device.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccdelayed,
|
||||
"errors_corrected_by_rereads_rewrites": device.ScsiErrorCounterLog.Write.ErrorsCorrectedByRereadsRewrites,
|
||||
"total_errors_corrected": device.ScsiErrorCounterLog.Write.TotalErrorsCorrected,
|
||||
"correction_algorithm_invocations": device.ScsiErrorCounterLog.Write.CorrectionAlgorithmInvocations,
|
||||
"gigabytes_processed": device.ScsiErrorCounterLog.Write.GigabytesProcessed,
|
||||
"total_uncorrected_errors": device.ScsiErrorCounterLog.Write.TotalUncorrectedErrors,
|
||||
}
|
||||
acc.AddFields("smartctl_scsi_error_counter_log", fields, counterTags, t)
|
||||
|
||||
counterTags["page"] = "verify"
|
||||
fields = map[string]interface{}{
|
||||
"errors_corrected_by_eccfast": device.ScsiErrorCounterLog.Verify.ErrorsCorrectedByEccfast,
|
||||
"errors_corrected_by_eccdelayed": device.ScsiErrorCounterLog.Verify.ErrorsCorrectedByEccdelayed,
|
||||
"errors_corrected_by_rereads_rewrites": device.ScsiErrorCounterLog.Verify.ErrorsCorrectedByRereadsRewrites,
|
||||
"total_errors_corrected": device.ScsiErrorCounterLog.Verify.TotalErrorsCorrected,
|
||||
"correction_algorithm_invocations": device.ScsiErrorCounterLog.Verify.CorrectionAlgorithmInvocations,
|
||||
"gigabytes_processed": device.ScsiErrorCounterLog.Verify.GigabytesProcessed,
|
||||
"total_uncorrected_errors": device.ScsiErrorCounterLog.Verify.TotalUncorrectedErrors,
|
||||
}
|
||||
acc.AddFields("smartctl_scsi_error_counter_log", fields, counterTags, t)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue