Add drive SMART attributes and health status
This commit is contained in:
1 parent
40109b5c62
commit
23d7e79605
3 files changed
+128
-6
No files matched your search
@@ -24,6 +24,45 @@ def drive_type(name)
|
||||
rotational == "1" ? "hdd" : "ssd"
|
||||
end
|
||||
|
||||
def read_smart(name)
|
||||
out = `smartctl -j -A -H /dev/#{name} 2>/dev/null`
|
||||
return nil if out.empty?
|
||||
data = JSON.parse(out) rescue nil
|
||||
return nil unless data
|
||||
|
||||
result = {}
|
||||
passed = data.dig("smart_status", "passed")
|
||||
result["passed"] = passed unless passed.nil?
|
||||
|
||||
if (t = data.dig("temperature", "current"))
|
||||
result["temperature"] = t
|
||||
end
|
||||
if (poh = data.dig("power_on_time", "hours"))
|
||||
result["power_on_hours"] = poh
|
||||
end
|
||||
|
||||
if name.start_with?("nvme")
|
||||
log = data["nvme_smart_health_information_log"] || {}
|
||||
result["percentage_used"] = log["percentage_used"] if log.key?("percentage_used")
|
||||
result["media_errors"] = log["media_errors"] if log.key?("media_errors")
|
||||
result["critical_warning"] = log["critical_warning"] if log.key?("critical_warning")
|
||||
else
|
||||
attrs = data.dig("ata_smart_attributes", "table") || []
|
||||
attrs.each do |a|
|
||||
raw = a.dig("raw", "value")
|
||||
next if raw.nil?
|
||||
case a["id"]
|
||||
when 5 then result["reallocated_sectors"] = raw
|
||||
when 10 then result["spin_retry"] = raw
|
||||
when 197 then result["pending_sectors"] = raw
|
||||
when 199 then result["crc_errors"] = raw
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def handle_info(conn)
|
||||
info = []
|
||||
|
||||
@@ -37,12 +76,17 @@ def handle_info(conn)
|
||||
model = (File.read("#{block_path}/device/model").strip rescue "Unknown")
|
||||
bytes = File.read("#{block_path}/size").strip.to_i * 512
|
||||
|
||||
info << {
|
||||
entry = {
|
||||
"type" => "drive",
|
||||
"drivetype" => drive_type(name),
|
||||
"name" => name,
|
||||
"model" => model,
|
||||
"capacity" => human_capacity(bytes)
|
||||
}
|
||||
if (smart = read_smart(name))
|
||||
entry["smart"] = smart
|
||||
end
|
||||
info << entry
|
||||
end
|
||||
|
||||
if conn
|
||||
|
||||
Reference in new issue
Block a user