2023-08-19 13:13:09 +02:00
|
|
|
#!/usr/bin/python3
|
|
|
|
import argparse
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
import time
|
|
|
|
|
|
|
|
import ltsdb_record
|
|
|
|
|
|
|
|
ap = argparse.ArgumentParser()
|
|
|
|
ap.add_argument("device")
|
|
|
|
args = ap.parse_args()
|
|
|
|
|
|
|
|
p = subprocess.run(["/usr/sbin/smartctl", "-A", args.device],
|
|
|
|
stdout=subprocess.PIPE, universal_newlines=True)
|
|
|
|
report0 = []
|
|
|
|
state = 0
|
|
|
|
for ln in p.stdout.splitlines():
|
|
|
|
if state == 0 and ln.startswith("ID# ATTRIBUTE_NAME"):
|
|
|
|
state = 1
|
|
|
|
elif state == 1 and ln == "":
|
|
|
|
state = 2
|
|
|
|
elif state == 1:
|
2023-08-19 13:55:43 +02:00
|
|
|
(id, attribute_name, flag, value, worst, thresh, type, updated, when_failed, raw_value) = ln.split(None, 9)
|
2023-08-19 13:13:09 +02:00
|
|
|
|
2023-08-19 13:55:43 +02:00
|
|
|
if attribute_name == "Command_Timeout":
|
|
|
|
# This is a tuple of three values and I don't know what they mean
|
|
|
|
# so I just skip them.
|
|
|
|
# I guess I could just record them as smart_command_timeout_1,
|
|
|
|
# smart_command_timeout_2 and smart_command_timeout_3 ...
|
|
|
|
continue
|
2023-08-19 13:13:09 +02:00
|
|
|
if "_Ct" in attribute_name or "_Count" in attribute_name or "_Cnt" in attribute_name:
|
|
|
|
unit = "count"
|
|
|
|
elif "_Hours" in attribute_name:
|
|
|
|
unit = "hours"
|
|
|
|
elif "Total_LBAs_Written" in attribute_name:
|
|
|
|
unit = "blocks"
|
|
|
|
elif "Temperature_Cel" in attribute_name:
|
|
|
|
unit = "°C"
|
|
|
|
else:
|
|
|
|
unit = "unknown"
|
|
|
|
|
2023-08-19 13:55:43 +02:00
|
|
|
if unit == "°C":
|
|
|
|
# Sometimes there is extra information included - just ignore that.
|
|
|
|
value = int(raw_value.split()[0])
|
|
|
|
elif unit == "hours":
|
|
|
|
if m := re.match(r"([0-9]+)h\+([0-9]+)m\+([0-9.]+)s", raw_value):
|
|
|
|
# e.g. 60633h+54m+11.557s
|
|
|
|
value = (int(m.group(1)) * 3600 + int(m.group(2)) * 60 + float(m.group(2))) / 3600
|
|
|
|
else:
|
|
|
|
value = int(raw_value)
|
|
|
|
else:
|
|
|
|
value = int(raw_value)
|
|
|
|
|
2023-08-19 13:13:09 +02:00
|
|
|
report0.append(
|
|
|
|
{
|
|
|
|
"measure": "smart_" + attribute_name.lower(),
|
|
|
|
"unit": unit,
|
2023-08-19 13:55:43 +02:00
|
|
|
"value": value,
|
2023-08-19 13:13:09 +02:00
|
|
|
})
|
|
|
|
now = time.time()
|
|
|
|
report = [
|
|
|
|
{
|
|
|
|
"description": {
|
|
|
|
"hostname": ltsdb_record.node,
|
|
|
|
"device": args.device,
|
|
|
|
"measure": r["measure"],
|
|
|
|
"unit": r["unit"],
|
|
|
|
},
|
|
|
|
"data": [
|
|
|
|
[now, r["value"]]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
for r in report0
|
|
|
|
]
|
|
|
|
|
|
|
|
success = ltsdb_record.record_observations(report)
|
|
|
|
exit(1 - success)
|
|
|
|
|