""" Look through ZFS logs to find latest scrub and its output. Note that ZFS doesn't normally produce logs in /var/log, so for this to work, we must set up a cron job to dump `zpool iostat` into a file (hourly is best): `zpool iostat > /var/log/zpool.log && zpool status >> /var/log/zpool.log` The file gets overwritten every hour, so if more than one scrub occurs between logparse runs, it will only get the latest one. TODO: add feature to specify pools to check in config file TODO: set critical value for scrub data repair """ import re import sys, traceback from logparse.formatting import * from logparse.util import readlog from logparse.config import prefs from logparse.load_parsers import Parser class Zfs(Parser): def __init__(self): super().__init__() self.name = "zfs" self.info = "Look through ZFS logs to find latest scrub and its output" def parse_log(self): logger.debug("Starting zfs section") section = Section("zfs") zfslog = readlog(prefs.get("logs", "zfs")) logger.debug("Analysing zpool log") pool = re.search('.*---\n(\w*)', zfslog).group(1) scrub = re.search(".* scrub repaired (\d+\s*\w+) in .* with (\d+) " "errors on (\w+)\s+(\w+)\s+(\d+)\s+(\d{1,2}:\d{2}):" "\d+\s+(\d{4})", zfslog) logger.debug("Found groups {0}".format(scrub.groups())) iostat = re.search('.*---\n\w*\s*(\S*)\s*(\S*)\s', zfslog) scrubrepairs = scruberrors = scrubdate = None alloc = iostat.group(1) free = iostat.group(2) try: scrubrepairs = scrub.group(1) scruberrors = scrub.group(2) scrubdate = ' '.join(scrub.groups()[2:-1]) except Exception as e: logger.debug("Error getting scrub data: " + str(e)) traceback.print_exc(limit=2, file=sys.stdout) if (scrubdate != None): scrub_data = Data("Scrub of " + pool + " on " + scrubdate) scrub_data.items = [scrubrepairs + " repaired", scruberrors + " errors", alloc + " used", free + " free"] else: scrub_data = Data(pool) scrub_data.items = [alloc + " used", free + " free"] section.append_data(scrub_data) logger.info("Finished zfs section") return section