return False
def get_stats(self, pool_id):
- pass
+ socket_path = self._get_state_file_path(pool_id, 'sock')
+ if os.path.exists(socket_path):
+ try:
+ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ s.connect(socket_path)
+ s.send('show stat -1 2 -1\n')
+ raw_stats = ''
+ chunk_size = 1024
+ while True:
+ chunk = s.recv(chunk_size)
+ raw_stats += chunk
+ if len(chunk) < chunk_size:
+ break
+
+ return self._parse_stats(raw_stats)
+ except socket.error, e:
+ LOG.warn(_('Error while connecting to stats socket: %s') % e)
+ return {}
+ else:
+ LOG.warn(_('Stats socket not found for pool %s') % pool_id)
+ return {}
+
+ def _parse_stats(self, raw_stats):
+ stat_lines = raw_stats.splitlines()
+ if len(stat_lines) < 2:
+ return {}
+ stat_names = [line.strip('# ') for line in stat_lines[0].split(',')]
+ stat_values = [line.strip() for line in stat_lines[1].split(',')]
+ stats = dict(zip(stat_names, stat_values))
+ unified_stats = {}
+ for stat in hacfg.STATS_MAP:
+ unified_stats[stat] = stats.get(hacfg.STATS_MAP[stat], '')
+
+ return unified_stats
def remove_orphans(self, known_pool_ids):
raise NotImplementedError()
])
self.assertTrue(self.driver.exists('pool_id'))
+
+ def test_get_stats(self):
+ raw_stats = ('# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,'
+ 'dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,'
+ 'act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,'
+ 'sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,'
+ 'check_status,check_code,check_duration,hrsp_1xx,'
+ 'hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,'
+ 'req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,\n'
+ '8e271901-69ed-403e-a59b-f53cf77ef208,BACKEND,1,2,3,4,0,'
+ '10,7764,2365,0,0,,0,0,0,0,UP,1,1,0,,0,103780,0,,1,2,0,,0'
+ ',,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,\n\n')
+ raw_stats_empty = ('# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,'
+ 'bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,'
+ 'status,weight,act,bck,chkfail,chkdown,lastchg,'
+ 'downtime,qlimit,pid,iid,sid,throttle,lbtot,'
+ 'tracked,type,rate,rate_lim,rate_max,check_status,'
+ 'check_code,check_duration,hrsp_1xx,hrsp_2xx,'
+ 'hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,'
+ 'req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,'
+ '\n')
+ with contextlib.nested(
+ mock.patch.object(self.driver, '_get_state_file_path'),
+ mock.patch('socket.socket'),
+ mock.patch('os.path.exists'),
+ ) as (gsp, socket, path_exists):
+ gsp.side_effect = lambda x, y: '/pool/' + y
+ path_exists.return_value = True
+ socket.return_value = socket
+ socket.recv.return_value = raw_stats
+
+ exp_stats = {'CONNECTION_ERRORS': '0',
+ 'CURRENT_CONNECTIONS': '1',
+ 'CURRENT_SESSIONS': '3',
+ 'IN_BYTES': '7764',
+ 'MAX_CONNECTIONS': '2',
+ 'MAX_SESSIONS': '4',
+ 'OUT_BYTES': '2365',
+ 'RESPONSE_ERRORS': '0',
+ 'TOTAL_SESSIONS': '10'}
+ stats = self.driver.get_stats('pool_id')
+ self.assertEqual(exp_stats, stats)
+
+ socket.recv.return_value = raw_stats_empty
+ self.assertEqual({}, self.driver.get_stats('pool_id'))
+
+ path_exists.return_value = False
+ socket.reset_mock()
+ self.assertEqual({}, self.driver.get_stats('pool_id'))
+ self.assertFalse(socket.called)