start_parse/parse.py
2020-07-01 16:11:27 -04:00

109 lines
2.7 KiB
Python

#!/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(*[(i,parsed[i].get('SMART Health Status')) for i in parsed], sep='\n')