From fb4f04fb768ff47ff2c971f801bf923d397ed62d Mon Sep 17 00:00:00 2001 From: petrucci4prez Date: Mon, 29 May 2017 21:15:38 -0400 Subject: [PATCH] subclass TimedRotatingFileHandler --- main.py | 10 ++-- sharedLogging.py | 122 ++++++++++++++++++++++++++--------------------- 2 files changed, 73 insertions(+), 59 deletions(-) diff --git a/main.py b/main.py index db081a0..dbfd6dd 100755 --- a/main.py +++ b/main.py @@ -4,6 +4,9 @@ import os, time, signal, traceback import RPi.GPIO as GPIO from auxilary import fallbackLogger +from sharedLogging import MasterLogger + +logger = MasterLogger(__name__, 'DEBUG') def printTrace(t): fallbackLogger(__name__, 'CRITICAL', '\n' + t) @@ -18,7 +21,7 @@ def clean(): try: logger.info('Terminated root process - PID: %s', os.getpid()) - logger.stop() + logger.unmountGluster() except NameError: pass except Exception: @@ -35,9 +38,8 @@ if __name__ == '__main__': GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) - from sharedLogging import MasterLogger - logger = MasterLogger(__name__, 'DEBUG') - + logger.mountGluster() + from notifier import criticalError from stateMachine import StateMachine diff --git a/sharedLogging.py b/sharedLogging.py index eb069ae..a5a70b0 100644 --- a/sharedLogging.py +++ b/sharedLogging.py @@ -1,55 +1,18 @@ -import logging, os +import logging, os, logging.handlers from subprocess import run, PIPE, CalledProcessError from logging.handlers import TimedRotatingFileHandler from auxilary import fallbackLogger -class GlusterFS(): +class GlusterFSHandler(TimedRotatingFileHandler): def __init__(self, server, volume, mountpoint, options=None): if not os.path.exists(mountpoint): raise FileNotFoundError - self.mountpoint = mountpoint - self.server = server - self.volume = volume - self.options = options - - def mount(self): - if os.path.ismount(self.mountpoint): - # NOTE: this assumes that the already-mounted device is the one intended - fallbackLogger(__name__, 'WARNING', 'Device already mounted at {}'.format(self.mountpoint)) - else: - dst = self.server + ':/' + self.volume - cmd = ['mount', '-t', 'glusterfs', dst, self.mountpoint] - if self.options: - cmd[1:1] = ['-o', self.options] - self._run(cmd) - - def unmount(self): - self._run(['umount', self.mountpoint]) - - def _run(self, cmd): - try: - run(cmd, check=True, stdout=PIPE, stderr=PIPE) - except CalledProcessError as e: - # we assume that this will only get thrown when the logger is not - # active, so use fallback to get the explicit mount errors - stderr=e.stderr.decode('ascii').rstrip() - fallbackLogger(__name__, 'CRITICAL', stderr) - raise SystemExit - -class MasterLogger(): - def __init__(self, name, level): - mountpoint = '/mnt/glusterfs/pyledriver' - - self.fs = GlusterFS('192.168.11.39', 'pyledriver', mountpoint, 'backupvolfile-server=192.168.11.48') - self.fs.mount() - - consoleFormat = logging.Formatter('[%(name)s] [%(levelname)s] %(message)s') - fileFormat = logging.Formatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s') - - console = logging.StreamHandler() - console.setFormatter(consoleFormat) + self._mountpoint = mountpoint + self._server = server + self._volume = volume + self._options = options logdest = mountpoint + '/logs' @@ -60,21 +23,70 @@ class MasterLogger(): 'Please (re)move this file to prevent data loss'.format(logdest)) raise SystemExit - self.rotatingFile = TimedRotatingFileHandler(logdest + '/pyledriver-log', when='midnight') - self.rotatingFile.setFormatter(fileFormat) + self._mount() + + super().__init__(logdest + '/pyledriver-log', when='midnight') + + fmt = logging.Formatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s') + self.setFormatter(fmt) + + def _mount(self): + if os.path.ismount(self._mountpoint): + # NOTE: this assumes that the already-mounted device is the one intended + fallbackLogger(__name__, 'WARNING', 'Device already mounted at {}'.format(self._mountpoint)) + else: + dst = self._server + ':/' + self._volume + cmd = ['mount', '-t', 'glusterfs', dst, self._mountpoint] + if self._options: + cmd[1:1] = ['-o', self._options] + self._run(cmd) + + def _unmount(self): + self._run(['umount', self._mountpoint]) + + def _run(self, cmd): + try: + run(cmd, check=True, stdout=PIPE, stderr=PIPE) + except CalledProcessError as e: + # we assume that this will only get thrown when the logger is not + # active, so use fallback to get the explicit mount errors + stderr = e.stderr.decode('ascii').rstrip() + fallbackLogger(__name__, 'CRITICAL', stderr) + raise SystemExit + + def close(self): + TimedRotatingFileHandler.close(self) # must close file stream before unmounting + self._unmount() + +class MasterLogger(): + def __init__(self, name, level): + self._console = logging.StreamHandler() + self._formatConsole(False) - self.rootLogger = logging.getLogger() - self.rootLogger.addHandler(console) - self.rootLogger.addHandler(self.rotatingFile) - self.rootLogger.setLevel(getattr(logging, level)) - - logger = logging.getLogger(name) + self._rootLogger = logging.getLogger() + self._rootLogger.addHandler(self._console) + self._rootLogger.setLevel(getattr(logging, level)) # since the logger module sucks and doesn't allow me to init # a logger in a subclass, need to "fake" object inheritance for i in ['debug', 'info', 'warning', 'error', 'critical']: - setattr(self, i, getattr(logger, i)) + setattr(self, i, getattr(logging.getLogger(name), i)) - def stop(self): - self.rotatingFile.close() # must close file stream before unmounting - self.fs.unmount() + def mountGluster(self): + self._gluster = GlusterFSHandler( + server = '192.168.11.39', + volume = 'pyledriver', + mountpoint = '/mnt/glusterfs/pyledriver', + options = 'backupvolfile-server=192.168.11.48' + ) + self._formatConsole(True) + self._rootLogger.addHandler(self._gluster) + + def unmountGluster(self): + self._rootLogger.removeHandler(self._gluster) + self._formatConsole(False) + + def _formatConsole(self, rotatingFile=False): + c = '' if rotatingFile else '[CONSOLE ONLY] ' + fmt = logging.Formatter('[%(name)s] [%(levelname)s] ' + c + '%(message)s') + self._console.setFormatter(fmt)