Created
January 17, 2023 06:55
-
-
Save wmantly/62da1444f523945bcc7e38d4fca41dad to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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