Skip to content

Instantly share code, notes, and snippets.

@wmantly
Last active November 9, 2019 18:56
Show Gist options
  • Save wmantly/7bceb3db1a2161151dd8bca3326863f3 to your computer and use it in GitHub Desktop.
Save wmantly/7bceb3db1a2161151dd8bca3326863f3 to your computer and use it in GitHub Desktop.
{
"/dev/disk/by-id/scsi-35000c50034b0014f": {
"Elements in grown defect list": "29",
"Non-medium error count": "54",
"SMART Health Status": "OK",
"read": {
"Correction algorithm invocations": "1",
"ECC corrected delayed": "1",
"ECC corrected fast": "2075731551",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "57328.942",
"Total errors corrected": "2075731552",
"Total uncorrected errors": "0"
},
"verify": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "424460285",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "0.000",
"Total errors corrected": "424460285",
"Total uncorrected errors": "0"
},
"write": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "0",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "10365.525",
"Total errors corrected": "0",
"Total uncorrected errors": "0"
}
},
"/dev/disk/by-id/scsi-35000c50040c6a15b": {
"Elements in grown defect list": "8199",
"Non-medium error count": "411",
"SMART Health Status": "FAILURE PREDICTION THRESHOLD EXCEEDED [asc=5d, ascq=0]",
"read": {
"Correction algorithm invocations": "13356",
"ECC corrected delayed": "13342",
"ECC corrected fast": "1460924525",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "72433.811",
"Total errors corrected": "1460937867",
"Total uncorrected errors": "14"
},
"verify": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "318183313",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "0.000",
"Total errors corrected": "318183313",
"Total uncorrected errors": "0"
},
"write": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "0",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "27903.330",
"Total errors corrected": "0",
"Total uncorrected errors": "0"
}
},
"/dev/disk/by-id/scsi-35000c5006248db97": {
"Elements in grown defect list": "0",
"Non-medium error count": "10",
"SMART Health Status": "OK",
"read": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "5122319",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "17033.444",
"Total errors corrected": "5122319",
"Total uncorrected errors": "0"
},
"verify": {},
"write": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "0",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "1778.742",
"Total errors corrected": "0",
"Total uncorrected errors": "0"
}
},
"/dev/disk/by-id/scsi-35000c5006248dcfb": {
"Elements in grown defect list": "0",
"Non-medium error count": "0",
"SMART Health Status": "OK",
"read": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "4642620",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "17217.414",
"Total errors corrected": "4642620",
"Total uncorrected errors": "0"
},
"verify": {},
"write": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "0",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "1918.898",
"Total errors corrected": "0",
"Total uncorrected errors": "0"
}
},
"/dev/disk/by-id/scsi-35000c50062502b8b": {
"Elements in grown defect list": "7",
"Non-medium error count": "10",
"SMART Health Status": "OK",
"read": {
"Correction algorithm invocations": "9",
"ECC corrected delayed": "9",
"ECC corrected fast": "314381026",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "229560.893",
"Total errors corrected": "314381035",
"Total uncorrected errors": "0"
},
"verify": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "64",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "0.000",
"Total errors corrected": "64",
"Total uncorrected errors": "0"
},
"write": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "0",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "47847.879",
"Total errors corrected": "0",
"Total uncorrected errors": "0"
}
},
"/dev/disk/by-id/scsi-35000c50083c40f03": {
"Elements in grown defect list": "0",
"Non-medium error count": "1",
"SMART Health Status": "OK",
"read": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "5353833",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "1627.851",
"Total errors corrected": "5353833",
"Total uncorrected errors": "0"
},
"verify": {},
"write": {
"Correction algorithm invocations": "0",
"ECC corrected delayed": "0",
"ECC corrected fast": "0",
"ECC reread/rewrites": "0",
"Gigabytes processed [10^9 bytes]": "1098.085",
"Total errors corrected": "0",
"Total uncorrected errors": "0"
}
}
}
#!/usr/bin/env python3
import re, os
from subprocess import getoutput
keys = [
"ECC corrected fast",
"ECC corrected delayed",
"ECC reread/rewrites",
"Total errors corrected",
"Correction algorithm invocations",
"Gigabytes processed [10^9 bytes]",
"Total uncorrected errors",
]
def log(type, disk, message):
print("!!LOG", type, disk, message)
def get_all_scsi_path():
disks = os.listdir('/dev/disk/by-id/')
out = []
for disk in disks:
if disk.startswith('scsi') and 'part' not in disk:
out.append('/dev/disk/by-id/'+disk)
return out
def call_smart(disks):
out = {}
for disk in disks:
content = getoutput('smartctl -a {}'.format(disk))
content = parse_out(content, disk)
out[disk] = content
return out
def save_status(stats):
for disk in status:
for key in ['read', 'write', 'verify']:
if len(disk[key]) == 7:
db.add_status(disk, key, disk[key], disk['Non-medium error count'])
else:
log('missing', disk, '{} is missing values'.fotmat(key))
def parse_out(content, disk=''):
out = {
'read': {},
'write': {},
'verify': {},
'Non-medium error count': 0,
'Elements in grown defect list': 0,
'SMART Health Status': ''
}
try:
out['SMART Health Status'] = re.search(
r'SMART Health Status:\s+(?P<status>.+)', content
).group('status')
except AttributeError as error:
log('missing', disk, "SMART Health Status not found")
try:
out['Elements in grown defect list'] = re.search(
r'Elements in grown defect list:\s+(?P<number>\d+)', content
).group('number')
except AttributeError as error:
log('missing', disk, "Elements in grown defect list not found")
try:
out['Non-medium error count'] = re.search(
r'Non-medium error count:\s+(?P<number>\d+)', content
).group('number')
except AttributeError as error:
log('missing', disk, "Non-medium error count not found")
try:
content = content.split("Error counter log:")[1]
except IndexError:
log('failed', disk, 'Missing error information section')
return {}
for line in content.split('\n'):
if line.startswith('read:'):
line = re.sub(r'^[a-z:\s]+', '', line)
line = re.split(r'\s+', line)
out['read'] = dict(zip(keys, line))
continue
if line.startswith('write:'):
line = re.sub(r'^[a-z:\s]+', '', line)
line = re.split(r'\s+', line)
out['write'] = dict(zip(keys, line))
continue
if line.startswith('verify:'):
line = re.sub(r'^[a-z:\s]+', '', line)
line = re.split(r'\s+', line)
out['verify'] = dict(zip(keys, line))
continue
return out
if __name__ == "__main__":
import json
disks = get_all_scsi_path()
parsed = call_smart(disks)
print(json.dumps(parsed, indent=4, sort_keys=True))
print(
"SMART Health status overview:",
*[
'{} is "{}"'.format(disk, parsed[disk].get('SMART Health Status'))
for disk in parsed
],
sep='\n'
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment