class Refresher(Thread): def __init__(self, client): Thread.__init__(self) self.client = client self.daemon = True self.running = False self.cclient = None def _check_size(self, stat): if len(stat) > MAX_STATS: start = len(stat) - MAX_STATS stat[:] = stat[start:] def run(self): self.cclient = StatsClient(endpoint=self.client.stats_endpoint) stats = self.client.stats dstats = self.client.dstats self.running = True while self.running: for watcher, pid, stat in self.cclient: if watcher == 'circus': data = dstats else: data = stats[watcher] data.append(stat) #self._check_size(data) def stop(self): self.running = False self.cclient.stop()
def run(self): self.cclient = StatsClient(endpoint=self.client.stats_endpoint) stats = self.client.stats dstats = self.client.dstats self.running = True while self.running: for watcher, pid, stat in self.cclient: if watcher == 'circus': data = dstats else: data = stats[watcher] data.append(stat)
def test_handler(self): log = self._get_file() stream = {'stream': FileStream(log)} self._run_circus('circus.tests.test_stats_client.run_process', stdout_stream=stream, stderr_stream=stream, stats=True) time.sleep(.5) # checking that our system is live and running client = CircusClient() res = client.send_message('list') watchers = res['watchers'] watchers.sort() self.assertEqual(['circusd-stats', 'test'], watchers) # making sure the stats process run res = client.send_message('status', name='test') self.assertEqual(res['status'], 'active') res = client.send_message('status', name='circusd-stats') self.assertEqual(res['status'], 'active') # playing around with the stats now: we should get some ! from circus.stats.client import StatsClient client = StatsClient() next = client.iter_messages().next for i in range(10): watcher, pid, stat = next() self.assertTrue(watcher in ('test', 'circusd-stats', 'circus'), watcher)
def on_get_stats(self, msg): """This method is the one way to start a conversation with the socket. When sending a message here, the parameters are packt into the msg dictionary, which contains: - "streams", a list of streams that the client want to be notified about. - "get_processes", if it wants to include the subprocesses managed by this watcher or not (optional, defaults to False) The server sends back to the client some messages, on different channels: - "stats-<watchername>" sends memory and cpu info for the aggregation of stats. - stats-<watchername>-pids sends the list of pids for this watcher - "stats-<watchername>-<pid>" sends the information about specific pids for the different watchers (works only if "get_processes" is set to True when calling this method) """ # unpack the params streams = msg.get('watchers', []) streamsWithPids = msg.get('watchersWithPids', []) # if we want to supervise the processes of a watcher, then send the # list of pids trough a socket. for watcher in streamsWithPids: pids = [int(pid) for pid in client.get_pids(watcher)] channel = 'stats-{watcher}-pids'.format(watcher=watcher) self.send_data(channel, pids=pids) # Get the channels that are interesting to us and send back information # there when we got them. stats = StatsClient(endpoint=client.stats_endpoint) for watcher, pid, stat in stats: if watcher in streams or watcher in streamsWithPids: if pid is None: # means that it's the aggregation self.send_data('stats-{watcher}'.format(watcher=watcher), mem=stat['mem'], cpu=stat['cpu']) else: if watcher in streamsWithPids: self.send_data('stats-{watcher}-{pid}'\ .format(watcher=watcher, pid=pid), mem=stat['mem'], cpu=stat['cpu'])
def test_handler(self): log = self._get_file() stream = {'stream': FileStream(log)} cmd = 'circus.tests.test_stats_client.run_process' stdout_stream = stream stderr_stream = stream yield self.start_arbiter(cmd=cmd, stdout_stream=stdout_stream, stderr_stream=stderr_stream, stats=True, debug=False) # waiting for data to appear in the file stream empty = True while empty: with open(log) as f: empty = f.read() == '' yield tornado_sleep(.1) # checking that our system is live and running client = AsyncCircusClient(endpoint=self.arbiter.endpoint) res = yield client.send_message('list') watchers = sorted(res['watchers']) self.assertEqual(['circusd-stats', 'test'], watchers) # making sure the stats process run res = yield client.send_message('status', name='test') self.assertEqual(res['status'], 'active') res = yield client.send_message('status', name='circusd-stats') self.assertEqual(res['status'], 'active') # playing around with the stats now: we should get some ! from circus.stats.client import StatsClient client = StatsClient(endpoint=self.arbiter.stats_endpoint) message_iterator = client.iter_messages() for i in range(10): watcher, pid, stat = next(message_iterator) self.assertTrue(watcher in ('test', 'circusd-stats', 'circus'), watcher) yield self.stop_arbiter()
def test_handler(self): if os.getenv('TRAVIS', False): return log = self._get_file() stream = {'stream': FileStream(log)} self._run_circus('circus.tests.test_stats_client.run_process', stdout_stream=stream, stderr_stream=stream, stats=True) # waiting for data to appear in the file stream empty = True while empty: with open(log) as f: empty = f.read() == '' time.sleep(.1) # checking that our system is live and running client = CircusClient() res = client.send_message('list') watchers = res['watchers'] watchers.sort() self.assertEqual(['circusd-stats', 'test'], watchers) # making sure the stats process run res = client.send_message('status', name='test') self.assertEqual(res['status'], 'active') res = client.send_message('status', name='circusd-stats') self.assertEqual(res['status'], 'active') # playing around with the stats now: we should get some ! from circus.stats.client import StatsClient client = StatsClient() next = client.iter_messages().next for i in range(10): watcher, pid, stat = next() self.assertTrue(watcher in ('test', 'circusd-stats', 'circus'), watcher)
def on_get_stats(self, msg): """This method is the one way to start a conversation with the socket. When sending a message here, the parameters are packt into the msg dictionary, which contains: - "streams", a list of streams that the client want to be notified about. - "get_processes", if it wants to include the subprocesses managed by this watcher or not (optional, defaults to False) The server sends back to the client some messages, on different channels: - "stats-<watchername>" sends memory and cpu info for the aggregation of stats. - stats-<watchername>-pids sends the list of pids for this watcher - "stats-<watchername>-<pid>" sends the information about specific pids for the different watchers (works only if "get_processes" is set to True when calling this method) - "socket-stats" send the aggregation information about sockets. - "socket-stats-<fd>" sends information about a particular fd. """ # unpack the params streams = msg.get('watchers', []) streams_with_pids = msg.get('watchersWithPids', []) # if we want to supervise the processes of a watcher, then send the # list of pids trough a socket. If we asked about sockets, do the same # with their fds client = get_client() for watcher in streams_with_pids: if watcher == "sockets": fds = [s['fd'] for s in client.get_sockets()] self.send_data('socket-stats-fds', fds=fds) else: pids = [int(pid) for pid in client.get_pids(watcher)] channel = 'stats-{watcher}-pids'.format(watcher=watcher) self.send_data(channel, pids=pids) # Get the channels that are interesting to us and send back information # there when we got them. stats = StatsClient(endpoint=client.stats_endpoint) for watcher, pid, stat in stats: if not self._running: return if watcher == 'sockets': # if we get information about sockets and we explicitely # requested them, send back the information. if 'sockets' in streams_with_pids and 'fd' in stat: self.send_data('socket-stats-{fd}'.format(fd=stat['fd']), **stat) elif 'sockets' in streams and 'addresses' in stat: self.send_data('socket-stats', reads=stat['reads'], adresses=stat['addresses']) else: available_watchers = streams + streams_with_pids + ['circus'] # these are not sockets but normal watchers if watcher in available_watchers: if (watcher == 'circus' and stat.get('name', None) in available_watchers): self.send_data( 'stats-{watcher}'.format(watcher=stat['name']), mem=stat['mem'], cpu=stat['cpu'], age=stat['age']) else: if pid is None: # means that it's the aggregation self.send_data( 'stats-{watcher}'.format(watcher=watcher), mem=stat['mem'], cpu=stat['cpu'], age=stat['age']) else: if watcher in streams_with_pids: self.send_data('stats-{watcher}-{pid}'.format( watcher=watcher, pid=pid), mem=stat['mem'], cpu=stat['cpu'], age=stat['age'])