def main(daemon_mode=True): global prof # parse option parser = argparse.ArgumentParser() parser.add_argument('--pid', action='store', dest='pid', default=None, help='pid filename') parser.add_argument('--single', action='store_true', dest='singleMode', default=False, help='use single mode') parser.add_argument( '--hostname_file', action='store', dest='hostNameFile', default=None, help='to record the hostname where harvester is launched') parser.add_argument('--rotate_log', action='store_true', dest='rotateLog', default=False, help='rollover log files before launching harvester') parser.add_argument('--version', action='store_true', dest='showVersion', default=False, help='show version information and exit') parser.add_argument('--profile_output', action='store', dest='profileOutput', default=None, help='filename to save the results of profiler') parser.add_argument( '--profile_mode', action='store', dest='profileMode', default='s', help= 'profile mode. s (statistic), d (deterministic), or t (thread-aware)') parser.add_argument( '--memory_logging', action='store_true', dest='memLogging', default=False, help='add information of memory usage in each logging message') parser.add_argument('--foreground', action='store_true', dest='foreground', default=False, help='run in the foreground not to be daemonized') options = parser.parse_args() # show version information if options.showVersion: print("Version : {0}".format(panda_pkg_info.release_version)) print("Last commit : {0}".format(commit_timestamp.timestamp)) return # check pid if options.pid is not None and os.path.exists(options.pid): print("ERROR: Cannot start since lock file {0} already exists".format( options.pid)) return # uid and gid uid = pwd.getpwnam(harvester_config.master.uname).pw_uid gid = grp.getgrnam(harvester_config.master.gname).gr_gid # get umask umask = os.umask(0) os.umask(umask) # memory logging if options.memLogging: core_utils.enable_memory_profiling() # hostname if options.hostNameFile is not None: with open(options.hostNameFile, 'w') as f: f.write(socket.getfqdn()) # rollover log files if options.rotateLog: core_utils.do_log_rollover() if hasattr(_logger.handlers[0], 'doRollover'): _logger.handlers[0].doRollover() if daemon_mode and not options.foreground: # redirect messages to stdout stdoutHandler = logging.StreamHandler(sys.stdout) stdoutHandler.setFormatter(_logger.handlers[0].formatter) _logger.addHandler(stdoutHandler) # collect streams not to be closed by daemon files_preserve = [] for loggerName, loggerObj in iteritems( logging.Logger.manager.loggerDict): if loggerName.startswith('panda'): for handler in loggerObj.handlers: if hasattr(handler, 'stream'): files_preserve.append(handler.stream) sys.stderr = StdErrWrapper() # make daemon context dc = daemon.DaemonContext(stdout=sys.stdout, stderr=sys.stderr, uid=uid, gid=gid, umask=umask, files_preserve=files_preserve, pidfile=daemon.pidfile.PIDLockFile( options.pid)) else: dc = DummyContext() with dc: # remove pidfile to prevent child processes crashing in atexit if not options.singleMode: dc.pidfile = None core_utils.set_file_permission(options.pid) core_utils.set_file_permission(logger_config.daemon['logdir']) _logger.info("start : version = {0}, last_commit = {1}".format( panda_pkg_info.release_version, commit_timestamp.timestamp)) # stop event stopEvent = threading.Event() # profiler prof = None if options.profileOutput is not None: # run with profiler if options.profileMode == 'd': # deterministic prof = pprofile.Profile() elif options.profileMode == 't': # thread-aware prof = pprofile.ThreadProfile() else: # statistic prof = cProfile.Profile() # post process for profiler def disable_profiler(): global prof if prof is not None: # disable profiler prof.disable() # dump results prof.dump_stats(options.profileOutput) prof = None # signal handlers def catch_sigkill(sig, frame): disable_profiler() _logger.info('got signal={0}'.format(sig)) try: os.remove(options.pid) except: pass if os.getppid() == 1: os.killpg(os.getpgrp(), signal.SIGKILL) else: os.kill(os.getpid(), signal.SIGKILL) def catch_sigterm(sig, frame): stopEvent.set() try: os.remove(options.pid) except: pass # set handler if daemon_mode: signal.signal(signal.SIGINT, catch_sigkill) signal.signal(signal.SIGHUP, catch_sigkill) signal.signal(signal.SIGTERM, catch_sigkill) signal.signal(signal.SIGUSR2, catch_sigterm) # start master master = Master(single_mode=options.singleMode, stop_event=stopEvent, daemon_mode=daemon_mode) if master is None: prof = None else: # enable profiler if prof is not None: prof.enable() # run master master.start() # disable profiler disable_profiler() if daemon_mode: _logger.info('terminated')
def main(daemon_mode=True): global prof global options # parse option parser = argparse.ArgumentParser() parser.add_argument('--pid', action='store', dest='pid', default=None, help='pid filename') parser.add_argument('--single', action='store_true', dest='singleMode', default=False, help='use single mode') parser.add_argument('--hostname_file', action='store', dest='hostNameFile', default=None, help='to record the hostname where harvester is launched') parser.add_argument('--rotate_log', action='store_true', dest='rotateLog', default=False, help='rollover log files before launching harvester') parser.add_argument('--version', action='store_true', dest='showVersion', default=False, help='show version information and exit') parser.add_argument('--profile_output', action='store', dest='profileOutput', default=None, help='filename to save the results of profiler') parser.add_argument('--profile_mode', action='store', dest='profileMode', default='s', help='profile mode. s (statistic), d (deterministic), or t (thread-aware)') parser.add_argument('--memory_logging', action='store_true', dest='memLogging', default=False, help='add information of memory usage in each logging message') parser.add_argument('--foreground', action='store_true', dest='foreground', default=False, help='run in the foreground not to be daemonized') options = parser.parse_args() # show version information if options.showVersion: print ("Version : {0}".format(panda_pkg_info.release_version)) print ("Last commit : {0}".format(commit_timestamp.timestamp)) return # check pid if options.pid is not None and os.path.exists(options.pid): print ("ERROR: Cannot start since lock file {0} already exists".format(options.pid)) return # uid and gid uid = pwd.getpwnam(harvester_config.master.uname).pw_uid gid = grp.getgrnam(harvester_config.master.gname).gr_gid # get umask umask = os.umask(0) os.umask(umask) # memory logging if options.memLogging: core_utils.enable_memory_profiling() # hostname if options.hostNameFile is not None: with open(options.hostNameFile, 'w') as f: f.write(socket.getfqdn()) # rollover log files if options.rotateLog: core_utils.do_log_rollover() if hasattr(_logger.handlers[0], 'doRollover'): _logger.handlers[0].doRollover() if daemon_mode and not options.foreground: # redirect messages to stdout stdoutHandler = logging.StreamHandler(sys.stdout) stdoutHandler.setFormatter(_logger.handlers[0].formatter) _logger.addHandler(stdoutHandler) # collect streams not to be closed by daemon files_preserve = [] for loggerName, loggerObj in iteritems(logging.Logger.manager.loggerDict): if loggerName.startswith('panda'): for handler in loggerObj.handlers: if hasattr(handler, 'stream'): files_preserve.append(handler.stream) sys.stderr = StdErrWrapper() # make daemon context dc = daemon.DaemonContext(stdout=sys.stdout, stderr=sys.stderr, uid=uid, gid=gid, umask=umask, files_preserve=files_preserve, pidfile=daemon.pidfile.PIDLockFile(options.pid)) else: dc = DummyContext() with dc: # remove pidfile to prevent child processes crashing in atexit if not options.singleMode: dc.pidfile = None if options.pid: core_utils.set_file_permission(options.pid) core_utils.set_file_permission(logger_config.daemon['logdir']) _logger.info("start : version = {0}, last_commit = {1}".format(panda_pkg_info.release_version, commit_timestamp.timestamp)) # stop event stopEvent = threading.Event() # profiler prof = None if options.profileOutput is not None: # run with profiler if options.profileMode == 'd': # deterministic prof = pprofile.Profile() elif options.profileMode == 't': # thread-aware prof = pprofile.ThreadProfile() else: # statistic prof = cProfile.Profile() # post process for profiler def disable_profiler(): global prof if prof is not None: # disable profiler prof.disable() # dump results prof.dump_stats(options.profileOutput) prof = None # delete PID def delete_pid(pid): try: os.remove(pid) except Exception: pass # signal handlers def catch_sigkill(sig, frame): disable_profiler() _logger.info('got signal={0} to be killed'.format(sig)) try: os.remove(options.pid) except Exception: pass try: if os.getppid() == 1: os.killpg(os.getpgrp(), signal.SIGKILL) else: os.kill(os.getpid(), signal.SIGKILL) except Exception: core_utils.dump_error_message(_logger) _logger.error('failed to be killed') ''' def catch_sigterm(sig, frame): _logger.info('got signal={0} to be terminated'.format(sig)) stopEvent.set() # register del function if os.getppid() == 1 and options.pid: atexit.register(delete_pid, options.pid) # set alarm just in case signal.alarm(30) ''' def catch_debug(sig, frame): _logger.info('got signal={0} to go into debugger mode'.format(sig)) from trepan.interfaces import server from trepan.api import debug try: portNum = harvester_config.master.debugger_port except Exception: portNum = 19550 connection_opts = {'IO': 'TCP', 'PORT': portNum} interface = server.ServerInterface(connection_opts=connection_opts) dbg_opts = {'interface': interface} _logger.info('starting debugger on port {0}'.format(portNum)) debug(dbg_opts=dbg_opts) # set handler if daemon_mode: signal.signal(signal.SIGINT, catch_sigkill) signal.signal(signal.SIGHUP, catch_sigkill) signal.signal(signal.SIGTERM, catch_sigkill) signal.signal(signal.SIGALRM, catch_sigkill) signal.signal(signal.SIGUSR1, catch_debug) signal.signal(signal.SIGUSR2, catch_sigkill) # start master master = Master(single_mode=options.singleMode, stop_event=stopEvent, daemon_mode=daemon_mode) if master is None: prof = None else: # enable profiler if prof is not None: prof.enable() # run master master.start() # disable profiler disable_profiler() if daemon_mode: _logger.info('terminated')