def is_daemon_running(): global _PIDFILE_PATH global _PIDFILE_TIMEOUT lockfile = runner.make_pidlockfile(_PIDFILE_PATH, _PIDFILE_TIMEOUT) if lockfile.is_locked(): return True return False
def __daemon(self): """ Daemonizes the process; returns a non-zero exit code in case of failure. """ # Daemonize try: # Create and check PID file oPidLockFile = make_pidlockfile(self.__oArguments.pid, 0) if is_pidfile_stale(oPidLockFile): oPidLockFile.break_lock() if oPidLockFile.is_locked(): iPid = oPidLockFile.read_pid() logger.error(f"daemon: Process already running; PID={iPid}") return errno.EEXIST # Create daemon context oDaemonContext = DaemonContext(pidfile=oPidLockFile) oDaemonContext.signal_map = {signal.SIGTERM: self.__signal} oDaemonContext.open() emit_message(f"daemon: Forked to background; PID={os.getpid()}") # Redirect standard error to syslog oHandler = SysLogHandler(address="/dev/log") oHandler.setLevel(logger.level) oHandler.setFormatter( logging.Formatter( "%(name)s[%(process)d]: %(levelname)s: %(message)s")) logger.addHandler(oHandler) # Execute return self.__updater() except Exception as e: logger.error(f"daemon: Failed to fork to background; {str(e)}") return errno.ESRCH
def __init__(self, parser=parser, argv=None): # daemon use old __stdin__ semantic while multiprocessing eg. may not # care about it and close stdin without replacing __stdin__ sys.__stdin__ = sys.stdin self.parser = parser self.parse_args(argv) context_args = {} if not self.detach_process: context_args["stdin"] = sys.stdin context_args["stdout"] = sys.stdout context_args["stderr"] = sys.stderr dc = self.daemon_context = daemon.DaemonContext( umask=0o007, working_directory=self.wdir, detach_process=self.detach_process, **context_args ) owner = [-1, -1] if self.uid is not None: owner[0] = self.uid if self.gid is not None: owner[1] = self.gid if self.detach_process: log = open(self.log_path, "a+", buffering=0) os.chown(self.log_path, *owner) dc.stderr = log self.pidfile = dc.pidfile = make_pidlockfile(self.pid_path, 5000) if self.uid is not None: dc.uid = self.uid if self.gid is not None: dc.gid = self.gid handler = term_handler(self) dc.signal_map[signal.SIGTERM] = handler if not self.detach_process: dc.signal_map[signal.SIGINT] = handler
def __daemon(self): """ Daemonizes the process; returns a non-zero exit code in case of failure. """ # Daemonize try: # Create and check PID file oPidLockFile = make_pidlockfile(self.__oArguments.pid, 0) if is_pidfile_stale(oPidLockFile): oPidLockFile.break_lock() if oPidLockFile.is_locked(): sys.stderr.write( 'ERROR[Daemon]: Daemon process already running; PID=%s\n' % oPidLockFile.read_pid()) return errno.EEXIST # Create daemon context oDaemonContext = DaemonContext(pidfile=oPidLockFile) oDaemonContext.signal_map = {signal.SIGTERM: self.__signal} oDaemonContext.open() emit_message('[%s]' % os.getpid()) # Redirect standard error to syslog syslog.openlog('LogWatcher', syslog.LOG_PID, syslog.LOG_DAEMON) sys.stderr = Logger(self.__syslog) # Execute return self.__spawnWatchers(self.__oConfigObj) except Exception as e: sys.stderr.write( 'ERROR[Daemon]: Failed to fork to background; %s\n' % str(e)) return errno.ESRCH
def __init__(self, host=None, port=None, pidfile=None, logfile=None, daemonize=False, debug=False): if not logfile: logfile = app.config['WEB_LOG_FILE'] logfile = os.path.realpath(logfile) pidfile = os.path.realpath(pidfile or app.config['WEB_PID_FILE']) if daemonize: detach_process = True else: detach_process = False self.daemon_context = DaemonContext(detach_process=detach_process) self.daemon_context.stdout = open(logfile, 'w+') self.daemon_context.stderr = open(logfile, 'w+', buffering=0) self.pidfile = make_pidlockfile(pidfile, self.pidfile_timeout) self.daemon_context.pidfile = self.pidfile self.host = host or app.config['WEB_HOST'] self.port = port or app.config['WEB_PORT'] self.debug = debug # HACK: set app to self so self.app.run() works self.app = self
def cmd_run(argv): parser = argparse.ArgumentParser( prog="aio run", description='aio app runner') parser.add_argument( "-d", action="store_true", help="daemonize process") parsed, remainder = parser.parse_known_args() aio.app.logging.start_logging(aio.app.config) aio.app.signal.start_listeners(aio.app.config) if parsed.d: pidfile = runner.make_pidlockfile( os.path.abspath('var/run/aio.pd'), 1) if runner.is_pidfile_stale(pidfile): pidfile.break_lock() if pidfile.is_locked(): print( "There seems to be another aio process running " + "already, stop that one first") exit() class open_logs: def __enter__(self): return ( open("var/log/aio.log", "a"), open("var/log/aio.log", "a")) def __exit__(self, *la): pass with open_logs() as (stdout, stderr): daemon_context = dict( stdout=stdout, stderr=stderr, working_directory=os.getcwd(), pidfile=pidfile) dc = daemon.DaemonContext(**daemon_context) try: dc.open() app_runner() except lockfile.AlreadyLocked: print('LOCKFILE LOCKED') else: app_runner()
def __init__(self, app): self.parse_args() self.app = app self.daemon_context = DaemonContext() self.daemon_context.stdin = open(app.stdin_path, 'rt') self.daemon_context.stdout = open(app.stdout_path, 'w+t') if sys.version_info[0] >= 3: self.daemon_context.stderr = open( app.stderr_path, 'w+b', buffering=0) else: self.daemon_context.stderr = open( app.stderr_path, 'w+t', buffering=0) self.pidfile = None if app.pidfile_path is not None: self.pidfile = make_pidlockfile( app.pidfile_path, app.pidfile_timeout) self.daemon_context.pidfile = self.pidfile
def __init__(self, app): self.parse_args() self.app = app signalHandlerMap = {signal.SIGTERM: self.app.stop} uid = pwd.getpwnam(REPO_CONFIG.get('DAEMON_USER')).pw_uid gid = grp.getgrnam(REPO_CONFIG.get('DAEMON_GROUP')).gr_gid self.daemon_context = DaemonContext(signal_map=signalHandlerMap, working_directory='.', uid=uid, gid=gid, umask=022) self.daemon_context.stdin = None self.daemon_context.stdout = self.app.stdout self.daemon_context.stderr = self.app.stderr self.pidfile = None if app.pidfile_path is not None: self.pidfile = make_pidlockfile( app.pidfile_path, app.pidfile_timeout) self.daemon_context.pidfile = self.pidfile
def __init__(self, app): for cmd in app.EXTRA_CMDS: DaemonRunner.action_funcs[cmd] = getattr(app, cmd) self.parse_args() self._stdout_path = app.stdout_path self._stdin_path = app.stdin_path self._stderr_path = app.stderr_path with open(app.stdin_path, 'a'): pass if self.action not in self.START_CMDS: app.stdin_path = '/dev/null' app.stdout_path = '/dev/null' app.stderr_path = '/dev/null' elif self.action in self.START_CMDS: self.pidfile = make_pidlockfile(app.pidfile_path, app.pidfile_timeout) status = self._get_status() if status[0] == 1: print('app is running.') raise ValueError('app is running') self._rename_log(app.stdout_path) self._rename_log(app.stderr_path) #主微线程 self._main_let = getcurrent() def _wrap_run(func): """守护模式后,没有下面sleep, 某些(admin进程在socket.getaddrinfo)会在卡死 怀疑是gevent微线程切换问题,暂时这么处理 """ def _func(*args, **kw): sleep(0.05) return func(*args, **kw) return _func app.run = _wrap_run(app.start) DaemonRunner.__init__(self, app) self._init_signal()
def __init__(self, host=None, port=None, pidfile=None, logfile=None): from sentry.conf import settings if not logfile: logfile = settings.WEB_LOG_FILE self.daemon_context = DaemonContext() self.daemon_context.stdout = open(logfile, 'w+') self.daemon_context.stderr = open(logfile, 'w+', buffering=0) self.pidfile = make_pidlockfile(pidfile or settings.WEB_PID_FILE, self.pidfile_timeout) self.daemon_context.pidfile = self.pidfile self.host = host or settings.WEB_HOST self.port = port or settings.WEB_PORT # HACK: set app to self so self.app.run() works self.app = self
def __init__(self, app, parser): """ Set up the parameters of a new runner. The `app` argument must have the following attributes: * `stdin_path`: Filesystem path to open and replace `sys.stdin`. * `stdout_logger`, `stderr_logger`: Loggers to redirect the existing `sys.stdout` and `sys.stderr`. * `pidfile_path`: Absolute filesystem path to a file that will be used as the PID file for the daemon. If ``None``, no PID file will be used. * `pidfile_timeout`: Used as the default acquisition timeout value supplied to the runner's PID lock file. * `run`: Callable that will be invoked when the daemon is started. The `parser` argument must be an optparse.OptionParser() object. """ self.app = app self.parser = parser (options, args) = parser.parse_args() self.args = args self.options = options self.parse_args() self.daemon_context = DaemonContext() self.daemon_context.stdin = open(app.stdin_path, 'r') self.stdout_logger = app.stdout_logger self.stderr_logger = app.stderr_logger self.daemon_context.files_preserve = [] self.loggers_preserve = [] self.pidfile = None if app.pidfile_path is not None: self.pidfile = make_pidlockfile(app.pidfile_path, app.pidfile_timeout) self.daemon_context.pidfile = self.pidfile
def __init__(self, app, parser): """ Set up the parameters of a new runner. The `app` argument must have the following attributes: * `stdin_path`: Filesystem path to open and replace `sys.stdin`. * `stdout_logger`, `stderr_logger`: Loggers to redirect the existing `sys.stdout` and `sys.stderr`. * `pidfile_path`: Absolute filesystem path to a file that will be used as the PID file for the daemon. If ``None``, no PID file will be used. * `pidfile_timeout`: Used as the default acquisition timeout value supplied to the runner's PID lock file. * `run`: Callable that will be invoked when the daemon is started. The `parser` argument must be an optparse.OptionParser() object. """ self.app = app self.parser = parser (options, args) = parser.parse_args() self.args = args self.options = options self.parse_args() self.daemon_context = DaemonContext() self.daemon_context.stdin = open(app.stdin_path, 'r') self.stdout_logger = app.stdout_logger self.stderr_logger = app.stderr_logger self.daemon_context.files_preserve = [] self.loggers_preserve = [] self.pidfile = None if app.pidfile_path is not None: self.pidfile = make_pidlockfile( app.pidfile_path, app.pidfile_timeout) self.daemon_context.pidfile = self.pidfile
def __init__(self, app, pidfile=None, stdout=sys.stdout, stderr=sys.stderr, **options): """ Set up the parameters of a new runner. The `app` argument must have the following attributes: * `run`: Callable that will be invoked when the daemon is started. """ self.app = app if pidfile: self.pidfile = make_pidlockfile(pidfile, 5) else: self.pidfile = None self.daemon_context = DaemonContext( stdout=stdout, stderr=stderr, pidfile=self.pidfile, **options )
def __init__(self, app): self.parse_args() self.app = app signalHandlerMap = {signal.SIGTERM: self.app.stop} uid = pwd.getpwnam(REPO_CONFIG.get('DAEMON_USER')).pw_uid gid = grp.getgrnam(REPO_CONFIG.get('DAEMON_GROUP')).gr_gid self.daemon_context = DaemonContext(signal_map=signalHandlerMap, working_directory='.', uid=uid, gid=gid, umask=022) self.daemon_context.stdin = None self.daemon_context.stdout = self.app.stdout self.daemon_context.stderr = self.app.stderr self.pidfile = None if app.pidfile_path is not None: self.pidfile = make_pidlockfile(app.pidfile_path, app.pidfile_timeout) self.daemon_context.pidfile = self.pidfile
def __init__(self, app): for cmd in app.EXTRA_CMDS: DaemonRunner.action_funcs[cmd] = getattr(app, cmd) self.parse_args() self._stdout_path = app.stdout_path self._stdin_path = app.stdin_path self._stderr_path = app.stderr_path if self.action not in self.START_CMDS: app.stdin_path = '/dev/null' app.stdout_path = '/dev/null' app.stderr_path = '/dev/null' elif self.action in self.START_CMDS: self.pidfile = make_pidlockfile( app.pidfile_path, app.pidfile_timeout) status = self._get_status() if status[0] == 1: print 'app is running.' raise ValueError, 'app is running' self._rename_log(app.stdout_path) self._rename_log(app.stderr_path) #主微线程 self._main_let = getcurrent() def _wrap_run(func): """守护模式后,没有下面sleep, 某些(admin进程在socket.getaddrinfo)会在卡死 怀疑是gevent微线程切换问题,暂时这么处理 """ def _func(*args, **kw): sleep(0.05) return func(*args, **kw) return _func app.run = _wrap_run(app.run) DaemonRunner.__init__(self, app) self._init_signal()
def create(self): self.pidfile = make_pidlockfile(self.pidfile_path, self.pidfile_timeout) self.context = daemon.DaemonContext(working_directory = self.cwd, stdout = open(self.stdout_path, 'at+', buffering = 1), stderr = open(self.stderr_path, 'at+', buffering = 1)) self.context.pidfile = self.pidfile
def init_pidfile(self): self.pidfile = make_pidlockfile(TWITTER_CACHE_PID_FILE, self.pidfile_timeout)