def __init__(self, config): # Daemonize before doing any other setup if config.daemonize: daemonize() self.config = config self._children = ChildManager(config.cgroupdir, not config.oneshot) self._listener = ConnListener() self._last_log_prune = datetime.fromtimestamp(0) self._last_cache_prune = datetime.fromtimestamp(0) self._ignore_signals = False # Configure signals for sig in self.caught_signals: signal.signal(sig, self._handle_signal) # Configure logging baselog = logging.getLogger() baselog.setLevel(logging.DEBUG) if not config.daemonize: # In daemon mode, stderr goes to /dev/null, so don't bother # logging there. handler = logging.StreamHandler() baselog.addHandler(handler) self._logfile_handler = TimedRotatingFileHandler( os.path.join(config.logdir, 'diamondd.log'), when='midnight', backupCount=config.logdays) self._logfile_handler.setFormatter(_TimestampedLogFormatter()) baselog.addHandler(self._logfile_handler)
class DiamondServer(object): caught_signals = (signal.SIGINT, signal.SIGTERM, signal.SIGUSR1) def __init__(self, config): # Daemonize before doing any other setup if config.daemonize: daemonize() self.config = config self._children = ChildManager(config.cgroupdir, not config.oneshot) self._listener = ConnListener() self._last_log_prune = datetime.fromtimestamp(0) self._last_cache_prune = datetime.fromtimestamp(0) self._ignore_signals = False # Configure signals for sig in self.caught_signals: signal.signal(sig, self._handle_signal) # Configure logging baselog = logging.getLogger() baselog.setLevel(logging.DEBUG) if not config.daemonize: # In daemon mode, stderr goes to /dev/null, so don't bother # logging there. handler = logging.StreamHandler() baselog.addHandler(handler) self._logfile_handler = TimedRotatingFileHandler( os.path.join(config.logdir, 'diamondd.log'), when='midnight', backupCount=config.logdays) self._logfile_handler.setFormatter(_TimestampedLogFormatter()) baselog.addHandler(self._logfile_handler) # We intentionally catch all exceptions # pylint doesn't understand the conditional return in ConnListener.accept() # pylint: disable=broad-except,unpacking-non-sequence def run(self): try: # Log startup of parent _log.info('Starting supervisor %s, pid %d', opendiamond.__version__, os.getpid()) _log.info('Server IDs: %s', ', '.join(self.config.serverids)) if self.config.cache_server: _log.info('Cache: %s:%d', *self.config.cache_server) while True: # Check for search logs that need to be pruned self._prune_child_logs() # Check for blob cache objects that need to be pruned self._prune_blob_cache() # Accept a new connection pair control, data = self._listener.accept() # Fork a child for this connection pair. In the child, this # does not return. self._children.start(self._child, control, data) # Close the connection pair in the parent control.close() data.close() except _Signalled, s: _log.info('Supervisor exiting on %s', s.signame) # Stop listening for incoming connections self._listener.shutdown() # Kill our children and clean up after them self._children.kill_all() # Shut down logging logging.shutdown() # Ensure our exit status reflects that we died on the signal signal.signal(s.signal, signal.SIG_DFL) os.kill(os.getpid(), s.signal) except Exception: _log.exception('Supervisor exception') # Don't attempt to shut down cleanly; just flush logging buffers logging.shutdown() sys.exit(1)