2017-05-23 01:43:39 -04:00
|
|
|
import logging, os
|
2017-05-22 01:44:16 -04:00
|
|
|
from subprocess import run, PIPE, CalledProcessError
|
2016-12-30 02:51:56 -05:00
|
|
|
from logging.handlers import TimedRotatingFileHandler, QueueListener, QueueHandler
|
|
|
|
|
2017-05-22 02:32:19 -04:00
|
|
|
from auxilary import fallbackLogger
|
|
|
|
|
2016-12-30 02:51:56 -05:00
|
|
|
def SlaveLogger(name, level, queue):
|
|
|
|
logger = logging.getLogger(name)
|
|
|
|
logger.setLevel(getattr(logging, level))
|
|
|
|
logger.addHandler(QueueHandler(queue))
|
|
|
|
logger.propagate = False
|
|
|
|
return logger
|
2017-05-21 14:29:17 -04:00
|
|
|
|
2017-05-22 01:44:16 -04:00
|
|
|
class GlusterFS():
|
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
|
|
|
|
|
|
|
|
self.mountpoint = mountpoint
|
2017-05-23 01:18:46 -04:00
|
|
|
self.server = server
|
|
|
|
self.volume = volume
|
|
|
|
self.options = options
|
2017-05-22 01:44:16 -04:00
|
|
|
|
|
|
|
def mount(self):
|
2017-05-23 01:18:46 -04:00
|
|
|
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)
|
2017-05-22 01:44:16 -04:00
|
|
|
|
|
|
|
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:
|
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
|
|
|
|
stderr=e.stderr.decode('ascii').rstrip()
|
|
|
|
fallbackLogger(__name__, 'CRITICAL', stderr)
|
2017-05-23 01:43:39 -04:00
|
|
|
raise SystemExit
|
2017-05-22 02:32:19 -04:00
|
|
|
|
2016-12-30 02:51:56 -05:00
|
|
|
class MasterLogger():
|
|
|
|
def __init__(self, name, level, queue):
|
2017-05-22 01:44:16 -04:00
|
|
|
mountpoint = '/mnt/glusterfs/pyledriver'
|
|
|
|
|
2017-05-23 01:18:46 -04:00
|
|
|
self.fs = GlusterFS('192.168.11.39', 'pyledriver', mountpoint, 'backupvolfile-server=192.168.11.48')
|
2017-05-22 01:44:16 -04:00
|
|
|
self.fs.mount()
|
|
|
|
|
2016-12-30 02:51:56 -05:00
|
|
|
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)
|
|
|
|
|
2017-05-23 01:36:25 -04:00
|
|
|
logdest = mountpoint + '/logs'
|
|
|
|
|
|
|
|
if not os.path.exists(logdest):
|
|
|
|
os.mkdir(logdest)
|
|
|
|
elif os.path.isfile(logdest):
|
2017-05-23 01:43:39 -04:00
|
|
|
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
|
2017-05-23 01:36:25 -04:00
|
|
|
|
|
|
|
self.rotatingFile = TimedRotatingFileHandler(logdest + '/pyledriver-log', when='midnight')
|
2017-05-22 01:44:16 -04:00
|
|
|
self.rotatingFile.setFormatter(fileFormat)
|
2016-12-30 02:51:56 -05:00
|
|
|
|
|
|
|
logging.basicConfig(level=getattr(logging, level), handlers=[QueueHandler(queue)])
|
|
|
|
logger = logging.getLogger(name)
|
|
|
|
|
|
|
|
# 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))
|
|
|
|
|
2017-05-22 01:44:16 -04:00
|
|
|
self.queListener = QueueListener(queue, console, self.rotatingFile)
|
2016-12-30 02:51:56 -05:00
|
|
|
self.queListener.start()
|
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
self.queListener.stop()
|
2017-05-22 01:44:16 -04:00
|
|
|
self.rotatingFile.close() # must close file stream before unmounting
|
|
|
|
self.fs.unmount()
|