subclass TimedRotatingFileHandler

This commit is contained in:
petrucci4prez 2017-05-29 21:15:38 -04:00
parent f3abaa6e8c
commit fb4f04fb76
2 changed files with 73 additions and 59 deletions

10
main.py
View File

@ -4,6 +4,9 @@ import os, time, signal, traceback
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
from auxilary import fallbackLogger from auxilary import fallbackLogger
from sharedLogging import MasterLogger
logger = MasterLogger(__name__, 'DEBUG')
def printTrace(t): def printTrace(t):
fallbackLogger(__name__, 'CRITICAL', '\n' + t) fallbackLogger(__name__, 'CRITICAL', '\n' + t)
@ -18,7 +21,7 @@ def clean():
try: try:
logger.info('Terminated root process - PID: %s', os.getpid()) logger.info('Terminated root process - PID: %s', os.getpid())
logger.stop() logger.unmountGluster()
except NameError: except NameError:
pass pass
except Exception: except Exception:
@ -35,9 +38,8 @@ if __name__ == '__main__':
GPIO.setwarnings(False) GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) GPIO.setmode(GPIO.BCM)
from sharedLogging import MasterLogger logger.mountGluster()
logger = MasterLogger(__name__, 'DEBUG')
from notifier import criticalError from notifier import criticalError
from stateMachine import StateMachine from stateMachine import StateMachine

View File

@ -1,55 +1,18 @@
import logging, os import logging, os, logging.handlers
from subprocess import run, PIPE, CalledProcessError from subprocess import run, PIPE, CalledProcessError
from logging.handlers import TimedRotatingFileHandler from logging.handlers import TimedRotatingFileHandler
from auxilary import fallbackLogger from auxilary import fallbackLogger
class GlusterFS(): class GlusterFSHandler(TimedRotatingFileHandler):
def __init__(self, server, volume, mountpoint, options=None): def __init__(self, server, volume, mountpoint, options=None):
if not os.path.exists(mountpoint): if not os.path.exists(mountpoint):
raise FileNotFoundError raise FileNotFoundError
self.mountpoint = mountpoint self._mountpoint = mountpoint
self.server = server self._server = server
self.volume = volume self._volume = volume
self.options = options 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)
logdest = mountpoint + '/logs' logdest = mountpoint + '/logs'
@ -60,21 +23,70 @@ class MasterLogger():
'Please (re)move this file to prevent data loss'.format(logdest)) 'Please (re)move this file to prevent data loss'.format(logdest))
raise SystemExit raise SystemExit
self.rotatingFile = TimedRotatingFileHandler(logdest + '/pyledriver-log', when='midnight') self._mount()
self.rotatingFile.setFormatter(fileFormat)
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 = logging.getLogger()
self.rootLogger.addHandler(console) self._rootLogger.addHandler(self._console)
self.rootLogger.addHandler(self.rotatingFile) self._rootLogger.setLevel(getattr(logging, level))
self.rootLogger.setLevel(getattr(logging, level))
logger = logging.getLogger(name)
# since the logger module sucks and doesn't allow me to init # since the logger module sucks and doesn't allow me to init
# a logger in a subclass, need to "fake" object inheritance # a logger in a subclass, need to "fake" object inheritance
for i in ['debug', 'info', 'warning', 'error', 'critical']: 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): def mountGluster(self):
self.rotatingFile.close() # must close file stream before unmounting self._gluster = GlusterFSHandler(
self.fs.unmount() 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)