def start(self, dmd, reactor): """Start the servers. @param dmd {dmd} The dmd reference @param reactor {IReactor} Twisted reactor instance """ # Finish initialization modeling_paused = ModelingPaused(dmd, self.__modeling_pause_timeout) self.__worklist = ZenHubWorklist(modeling_paused=modeling_paused) # configure Metrology for the worklists register_metrics_on_worklist(self.__worklist) self.__workers = WorkerPool() self.__stats = StatsMonitor() self.__workerdispatcher = WorkerPoolDispatcher( reactor, self.__worklist, self.__workers, self.__stats, ) events = EventDispatcher(dmd.ZenEventManager) executor = DispatchingExecutor( [events], default=self.__workerdispatcher, ) service_factory = WorkerInterceptorFactory(executor) self.__services = HubServiceRegistry(dmd, service_factory) # Start the Perspective Broker server avatar = HubAvatar(self.__services, self.__workers) realm = HubRealm(avatar) checkers = getCredentialCheckers(self.__passwdfile) hubportal = portal.Portal(realm, checkers) hubserver_factory = ZenPBServerFactory(hubportal) tcp_version = "tcp6" if ipv6_available() else "tcp" pb_descriptor = "%s:port=%s" % (tcp_version, self.__pbport) pb_server = serverFromString(reactor, pb_descriptor) dfr = pb_server.listen(hubserver_factory) dfr.addCallback(self.__setKeepAlive) # Initialize and start the XMLRPC server self.__xmlrpc_site = AuthXmlRpcService.makeSite(dmd, checkers) xmlrpc_descriptor = "%s:port=%s" % (tcp_version, self.__xmlrpcport) xmlrpc_server = serverFromString(reactor, xmlrpc_descriptor) xmlrpc_server.listen(self.__xmlrpc_site)
def __init__(self, dmd, instance): from Products.ZenHub import ZENHUB_ZENRENDER if instance == ZENHUB_ZENRENDER: self.dmd = dmd self.instance = instance else: NullConfigService.__init__(self, dmd, instance) global htmlResource try: if not htmlResource: htmlResource = Render() log.info("Starting graph retrieval listener on port 8090") interface = '::' if ipv6_available() else '' reactor.listenTCP(8090, server.Site(htmlResource), interface=interface) htmlResource.addRenderer(self) except CannotListenError, e: # Probably in a hub worker; no big deal log.debug("Not starting render listener because the port is " "already in use.")
def postStartup(self): """ Listen for HTTP requests for RRD data or graphs. """ self._daemon = zope.component.getUtility(ICollector) # Start listening for HTTP requests httpPort = self. _daemon.options.httpport collector = self._daemon.options.monitor log.info("Starting %s zenrender webserver on port %s", collector, httpPort) renderer = HttpRender(collector) interface = '::' if ipv6_available() else '' reactor.listenTCP(httpPort, server.Site(renderer), interface=interface) # Add remote_ methods from renderer directly to the daemon for name in dir(renderer): if name.startswith('remote_'): func = getattr(renderer, name) setattr(self._daemon, name, func)
def postStartup(self): """ Listen for HTTP requests for RRD data or graphs. """ self._daemon = zope.component.getUtility(ICollector) # Start listening for HTTP requests httpPort = self._daemon.options.httpport collector = self._daemon.options.monitor log.info("Starting %s zenrender webserver on port %s", collector, httpPort) renderer = HttpRender(collector) interface = '::' if ipv6_available() else '' reactor.listenTCP(httpPort, server.Site(renderer), interface=interface) # Add remote_ methods from renderer directly to the daemon for name in dir(renderer): if name.startswith('remote_'): func = getattr(renderer, name) setattr(self._daemon, name, func)
def __init__(self): """ Hook ourselves up to the Zeo database and wait for collectors to connect. """ # list of remote worker references self.workers = [] self.workTracker = {} # zenhub execution stats: # [count, idle_total, running_total, last_called_time] self.executionTimer = collections.defaultdict(lambda: [0, 0.0, 0.0, 0]) self.workList = _ZenHubWorklist() # set of worker processes self.worker_processes = set() # map of worker pids -> worker processes self.workerprocessmap = {} self.shutdown = False self.counters = collections.Counter() self._invalidations_paused = False wl = self.workList metricNames = {x[0] for x in registry} class EventWorkList(Gauge): @property def value(self): return len(wl.eventworklist) if 'zenhub.eventWorkList' not in metricNames: Metrology.gauge('zenhub.eventWorkList', EventWorkList()) class ADMWorkList(Gauge): @property def value(self): return len(wl.applyworklist) if 'zenhub.admWorkList' not in metricNames: Metrology.gauge('zenhub.admWorkList', ADMWorkList()) class OtherWorkList(Gauge): @property def value(self): return len(wl.otherworklist) if 'zenhub.otherWorkList' not in metricNames: Metrology.gauge('zenhub.otherWorkList', OtherWorkList()) class WorkListTotal(Gauge): @property def value(self): return len(wl) if 'zenhub.workList' not in metricNames: Metrology.gauge('zenhub.workList', WorkListTotal()) ZCmdBase.__init__(self) import Products.ZenHub load_config("hub.zcml", Products.ZenHub) notify(HubWillBeCreatedEvent(self)) if self.options.profiling: self.profiler = ContinuousProfiler('zenhub', log=self.log) self.profiler.start() # Worker selection handler self.workerselector = WorkerSelector(self.options) self.workList.log = self.log # make sure we don't reserve more than n-1 workers for events maxReservedEventsWorkers = 0 if self.options.workers: maxReservedEventsWorkers = self.options.workers - 1 if self.options.workersReservedForEvents > maxReservedEventsWorkers: self.options.workersReservedForEvents = maxReservedEventsWorkers self.log.info( "reduced number of workers reserved for sending events to %d", self.options.workersReservedForEvents) self.zem = self.dmd.ZenEventManager loadPlugins(self.dmd) self.services = {} er = HubRealm(self) checker = self.loadChecker() pt = portal.Portal(er, [checker]) interface = '::' if ipv6_available() else '' pbport = reactor.listenTCP(self.options.pbport, pb.PBServerFactory(pt), interface=interface) self.setKeepAlive(pbport.socket) xmlsvc = AuthXmlRpcService(self.dmd, checker) reactor.listenTCP(self.options.xmlrpcport, server.Site(xmlsvc), interface=interface) # responsible for sending messages to the queues import Products.ZenMessaging.queuemessaging load_config_override('twistedpublisher.zcml', Products.ZenMessaging.queuemessaging) notify(HubCreatedEvent(self)) self.sendEvent(eventClass=App_Start, summary="%s started" % self.name, severity=0) self._initialize_invalidation_filters() reactor.callLater(self.options.invalidation_poll_interval, self.processQueue) self._metric_writer = metricWriter() self.rrdStats = self.getRRDStats() if self.options.workers: self.workerconfig = zenPath( 'var', 'zenhub', '{}_worker.conf'.format(self._getConf().id)) self._createWorkerConf() for i in range(self.options.workers): self.createWorker(i) # start cyclic call to giveWorkToWorkers reactor.callLater(2, self.giveWorkToWorkers, True) # set up SIGUSR2 handling try: signal.signal(signal.SIGUSR2, self.sighandler_USR2) except ValueError: # If we get called multiple times, this will generate an exception: # ValueError: signal only works in main thread # Ignore it as we've already set up the signal handler. pass # ZEN-26671 Wait at least this duration in secs # before signaling a worker process self.SIGUSR_TIMEOUT = 5
def version(self): if self.__version is None: self.__version = "tcp6" if ipv6_available() else "tcp" return self.__version