2017-05-29 21:15:38 -04:00
|
|
|
import logging, os, logging.handlers
|
2017-05-22 01:44:16 -04:00
|
|
|
from subprocess import run, PIPE, CalledProcessError
|
2017-05-29 18:04:50 -04:00
|
|
|
from logging.handlers import TimedRotatingFileHandler
|
2016-12-30 02:51:56 -05:00
|
|
|
|
2017-05-22 02:32:19 -04:00
|
|
|
from auxilary import fallbackLogger
|
|
|
|
|
2017-05-29 21:15:38 -04:00
|
|
|
class GlusterFSHandler(TimedRotatingFileHandler):
|
2017-05-23 01:18:46 -04:00
|
|
|
def __init__(self, server, volume, mountpoint, options=None):
|
2017-05-22 01:44:16 -04:00
|
|
|
if not os.path.exists(mountpoint):
|
|
|
|
raise FileNotFoundError
|
|
|
|
|
2017-05-29 21:15:38 -04:00
|
|
|
self._mountpoint = mountpoint
|
|
|
|
self._server = server
|
|
|
|
self._volume = volume
|
|
|
|
self._options = options
|
|
|
|
|
|
|
|
logdest = mountpoint + '/logs'
|
|
|
|
|
|
|
|
if not os.path.exists(logdest):
|
|
|
|
os.mkdir(logdest)
|
|
|
|
elif os.path.isfile(logdest):
|
|
|
|
fallbackLogger(__name__, 'CRITICAL', '{} is present but is a file (vs a directory). ' \
|
|
|
|
'Please (re)move this file to prevent data loss'.format(logdest))
|
|
|
|
raise SystemExit
|
|
|
|
|
|
|
|
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):
|
2017-05-23 01:18:46 -04:00
|
|
|
# NOTE: this assumes that the already-mounted device is the one intended
|
2017-05-29 21:15:38 -04:00
|
|
|
fallbackLogger(__name__, 'WARNING', 'Device already mounted at {}'.format(self._mountpoint))
|
2017-05-23 01:18:46 -04:00
|
|
|
else:
|
2017-05-29 21:15:38 -04:00
|
|
|
dst = self._server + ':/' + self._volume
|
|
|
|
cmd = ['mount', '-t', 'glusterfs', dst, self._mountpoint]
|
|
|
|
if self._options:
|
|
|
|
cmd[1:1] = ['-o', self._options]
|
2017-05-23 01:18:46 -04:00
|
|
|
self._run(cmd)
|
2017-05-22 01:44:16 -04:00
|
|
|
|
2017-05-29 21:15:38 -04:00
|
|
|
def _unmount(self):
|
|
|
|
self._run(['umount', self._mountpoint])
|
2017-05-22 01:44:16 -04:00
|
|
|
|
|
|
|
def _run(self, cmd):
|
|
|
|
try:
|
|
|
|
run(cmd, check=True, stdout=PIPE, stderr=PIPE)
|
|
|
|
except CalledProcessError as e:
|
2017-05-22 02:32:19 -04:00
|
|
|
# we assume that this will only get thrown when the logger is not
|
|
|
|
# active, so use fallback to get the explicit mount errors
|
2017-05-29 21:15:38 -04:00
|
|
|
stderr = e.stderr.decode('ascii').rstrip()
|
2017-05-22 02:32:19 -04:00
|
|
|
fallbackLogger(__name__, 'CRITICAL', stderr)
|
2017-05-23 01:43:39 -04:00
|
|
|
raise SystemExit
|
2017-05-29 21:15:38 -04:00
|
|
|
|
|
|
|
def close(self):
|
|
|
|
TimedRotatingFileHandler.close(self) # must close file stream before unmounting
|
|
|
|
self._unmount()
|
2017-05-22 02:32:19 -04:00
|
|
|
|
2016-12-30 02:51:56 -05:00
|
|
|
class MasterLogger():
|
2017-05-29 18:04:50 -04:00
|
|
|
def __init__(self, name, level):
|
2017-05-29 21:15:38 -04:00
|
|
|
self._console = logging.StreamHandler()
|
|
|
|
self._formatConsole(False)
|
2017-05-22 01:44:16 -04:00
|
|
|
|
2017-05-29 21:15:38 -04:00
|
|
|
self._rootLogger = logging.getLogger()
|
|
|
|
self._rootLogger.addHandler(self._console)
|
|
|
|
self._rootLogger.setLevel(getattr(logging, level))
|
2016-12-30 02:51:56 -05:00
|
|
|
|
|
|
|
# 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']:
|
2017-05-29 21:15:38 -04:00
|
|
|
setattr(self, i, getattr(logging.getLogger(name), i))
|
|
|
|
|
|
|
|
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)
|
2016-12-30 02:51:56 -05:00
|
|
|
|
2017-05-29 21:15:38 -04:00
|
|
|
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)
|