09db33ee935f730e79b125f3d2775a9262dfef63
   1#
   2#   zfs.py
   3#
   4#   Look through ZFS logs to find latest scrub and its output.
   5#   Note that ZFS doesn't normally produce logs in /var/log, so for this to
   6#   work, we must set up a cron job to dump `zpool iostat` into a file (hourly
   7#   is best):
   8#
   9#       zpool iostat > /var/log/zpool.log && zpool status >> /var/log/zpool.log
  10#
  11#   The file gets overwritten every hour, so if more than one scrub occurs
  12#   between logparse runs, it will only get the latest one.
  13#
  14#   TODO: add feature to specify pools to check in config file
  15#   TODO: set critical value for scrub data repair
  16#
  17
  18import re
  19import sys, traceback
  20
  21from ..formatting import *
  22from ..util import readlog, resolve
  23from .. import config
  24
  25import logging
  26logger = logging.getLogger(__name__)
  27
  28def parse_log():
  29    output = ''
  30    logger.debug("Starting zfs section")
  31    output += opentag('div', 1, 'zfs', 'section')
  32    zfslog = readlog(config.prefs['logs']['zfs'])
  33    logger.debug("Analysing zpool log")
  34    pool = re.search('.*---\n(\w*)', zfslog).group(1)
  35    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)
  36    logger.debug("Found groups {0}".format(scrub.groups()))
  37    iostat = re.search('.*---\n\w*\s*(\S*)\s*(\S*)\s', zfslog)
  38    scrubrepairs = scruberrors = scrubdate = None
  39    try:
  40        scrubrepairs = scrub.group(1)
  41        scruberrors = scrub.group(2)
  42        scrubdate = ' '.join(scrub.groups()[2:-1])
  43    except Exception as e:
  44        logger.debug("Error getting scrub data: " + str(e))
  45        traceback.print_exc(limit=2, file=sys.stdout)
  46    alloc = iostat.group(1)
  47    free = iostat.group(2)
  48    output += writetitle("zfs")
  49    if (scrubdate != None):
  50        subtitle = "Scrub of " + pool + " on " + scrubdate
  51        data = [scrubrepairs + " repaired", scruberrors + " errors", alloc + " used", free + " free"]
  52    else:
  53        subtitle = pool
  54        data = [alloc + " used", free + " free"]
  55    output += writedata(subtitle, data)
  56    output += closetag('div', 1)
  57    logger.info("Finished zfs section")
  58    return output