Skip to content

Instantly share code, notes, and snippets.

@wmantly
Created January 17, 2023 06:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmantly/62da1444f523945bcc7e38d4fca41dad to your computer and use it in GitHub Desktop.
Save wmantly/62da1444f523945bcc7e38d4fca41dad to your computer and use it in GitHub Desktop.
#!/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)
pass
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 -d scsi -a {}'.format(disk))
print(disk, content)
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(*[(i,parsed[i].get('SMART Health Status')) for i in parsed], sep='\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment