Exemple #1
0
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')
Exemple #2
0
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')