Add ceph df output to pool data
Allows additional information visible in the `ceph df` command, including pool free space and used percentage.
This commit is contained in:
parent
531578fd28
commit
356c12db2e
|
@ -131,6 +131,10 @@ def format_ops_fromhuman(datahuman):
|
||||||
dataops = datasize * ops_unit_matrix[dataunit]
|
dataops = datasize * ops_unit_matrix[dataunit]
|
||||||
return '{}'.format(dataops)
|
return '{}'.format(dataops)
|
||||||
|
|
||||||
|
def format_pct_tohuman(datapct):
|
||||||
|
datahuman = "{0:.1f}".format(float(datapct * 100.0))
|
||||||
|
return datahuman
|
||||||
|
|
||||||
#
|
#
|
||||||
# Status functions
|
# Status functions
|
||||||
#
|
#
|
||||||
|
@ -748,7 +752,9 @@ def format_list_pool(pool_list):
|
||||||
|
|
||||||
pool_name_length = 5
|
pool_name_length = 5
|
||||||
pool_id_length = 3
|
pool_id_length = 3
|
||||||
pool_size_length = 5
|
pool_used_length = 5
|
||||||
|
pool_usedpct_length = 5
|
||||||
|
pool_free_length = 5
|
||||||
pool_num_objects_length = 6
|
pool_num_objects_length = 6
|
||||||
pool_num_clones_length = 7
|
pool_num_clones_length = 7
|
||||||
pool_num_copies_length = 7
|
pool_num_copies_length = 7
|
||||||
|
@ -760,14 +766,18 @@ def format_list_pool(pool_list):
|
||||||
|
|
||||||
for pool_information in pool_list:
|
for pool_information in pool_list:
|
||||||
# Deal with the size to human readable
|
# Deal with the size to human readable
|
||||||
for datatype in 'size_bytes', 'write_bytes', 'read_bytes':
|
for datatype in ['free_bytes', 'used_bytes', 'write_bytes', 'read_bytes']:
|
||||||
databytes = pool_information['stats'][datatype]
|
databytes = pool_information['stats'][datatype]
|
||||||
databytes_formatted = format_bytes_tohuman(int(databytes))
|
databytes_formatted = format_bytes_tohuman(int(databytes))
|
||||||
pool_information['stats'][datatype] = databytes_formatted
|
pool_information['stats'][datatype] = databytes_formatted
|
||||||
for datatype in 'write_ops', 'read_ops':
|
for datatype in ['write_ops', 'read_ops']:
|
||||||
dataops = pool_information['stats'][datatype]
|
dataops = pool_information['stats'][datatype]
|
||||||
dataops_formatted = format_ops_tohuman(int(dataops))
|
dataops_formatted = format_ops_tohuman(int(dataops))
|
||||||
pool_information['stats'][datatype] = dataops_formatted
|
pool_information['stats'][datatype] = dataops_formatted
|
||||||
|
for datatype in ['used_percent']:
|
||||||
|
datapct = pool_information['stats'][datatype]
|
||||||
|
datapct_formatted = format_pct_tohuman(float(datapct))
|
||||||
|
pool_information['stats'][datatype] = datapct_formatted
|
||||||
|
|
||||||
# Set the Pool name length
|
# Set the Pool name length
|
||||||
_pool_name_length = len(pool_information['name']) + 1
|
_pool_name_length = len(pool_information['name']) + 1
|
||||||
|
@ -779,10 +789,20 @@ def format_list_pool(pool_list):
|
||||||
if _pool_id_length > pool_id_length:
|
if _pool_id_length > pool_id_length:
|
||||||
pool_id_length = _pool_id_length
|
pool_id_length = _pool_id_length
|
||||||
|
|
||||||
# Set the size and length
|
# Set the used and length
|
||||||
_pool_size_length = len(str(pool_information['stats']['size_bytes'])) + 1
|
_pool_used_length = len(str(pool_information['stats']['used_bytes'])) + 1
|
||||||
if _pool_size_length > pool_size_length:
|
if _pool_used_length > pool_used_length:
|
||||||
pool_size_length = _pool_size_length
|
pool_used_length = _pool_used_length
|
||||||
|
|
||||||
|
# Set the usedpct and length
|
||||||
|
_pool_usedpct_length = len(str(pool_information['stats']['used_percent'])) + 1
|
||||||
|
if _pool_usedpct_length > pool_usedpct_length:
|
||||||
|
pool_usedpct_length = _pool_usedpct_length
|
||||||
|
|
||||||
|
# Set the free and length
|
||||||
|
_pool_free_length = len(str(pool_information['stats']['free_bytes'])) + 1
|
||||||
|
if _pool_free_length > pool_free_length:
|
||||||
|
pool_free_length = _pool_free_length
|
||||||
|
|
||||||
# Set the num_objects and length
|
# Set the num_objects and length
|
||||||
_pool_num_objects_length = len(str(pool_information['stats']['num_objects'])) + 1
|
_pool_num_objects_length = len(str(pool_information['stats']['num_objects'])) + 1
|
||||||
|
@ -825,7 +845,9 @@ def format_list_pool(pool_list):
|
||||||
pool_list_output.append('{bold}\
|
pool_list_output.append('{bold}\
|
||||||
{pool_id: <{pool_id_length}} \
|
{pool_id: <{pool_id_length}} \
|
||||||
{pool_name: <{pool_name_length}} \
|
{pool_name: <{pool_name_length}} \
|
||||||
{pool_size: <{pool_size_length}} \
|
{pool_used: <{pool_used_length}} \
|
||||||
|
{pool_usedpct: <{pool_usedpct_length}} \
|
||||||
|
{pool_free: <{pool_free_length}} \
|
||||||
Obj: {pool_objects: <{pool_objects_length}} \
|
Obj: {pool_objects: <{pool_objects_length}} \
|
||||||
{pool_clones: <{pool_clones_length}} \
|
{pool_clones: <{pool_clones_length}} \
|
||||||
{pool_copies: <{pool_copies_length}} \
|
{pool_copies: <{pool_copies_length}} \
|
||||||
|
@ -839,7 +861,9 @@ Wr: {pool_write_ops: <{pool_write_ops_length}} \
|
||||||
end_bold=ansiprint.end(),
|
end_bold=ansiprint.end(),
|
||||||
pool_id_length=pool_id_length,
|
pool_id_length=pool_id_length,
|
||||||
pool_name_length=pool_name_length,
|
pool_name_length=pool_name_length,
|
||||||
pool_size_length=pool_size_length,
|
pool_used_length=pool_used_length,
|
||||||
|
pool_usedpct_length=pool_usedpct_length,
|
||||||
|
pool_free_length=pool_free_length,
|
||||||
pool_objects_length=pool_num_objects_length,
|
pool_objects_length=pool_num_objects_length,
|
||||||
pool_clones_length=pool_num_clones_length,
|
pool_clones_length=pool_num_clones_length,
|
||||||
pool_copies_length=pool_num_copies_length,
|
pool_copies_length=pool_num_copies_length,
|
||||||
|
@ -850,7 +874,9 @@ Wr: {pool_write_ops: <{pool_write_ops_length}} \
|
||||||
pool_read_data_length=pool_read_data_length,
|
pool_read_data_length=pool_read_data_length,
|
||||||
pool_id='ID',
|
pool_id='ID',
|
||||||
pool_name='Name',
|
pool_name='Name',
|
||||||
pool_size='Used',
|
pool_used='Used',
|
||||||
|
pool_usedpct='%',
|
||||||
|
pool_free='Free',
|
||||||
pool_objects='Count',
|
pool_objects='Count',
|
||||||
pool_clones='Clones',
|
pool_clones='Clones',
|
||||||
pool_copies='Copies',
|
pool_copies='Copies',
|
||||||
|
@ -867,7 +893,9 @@ Wr: {pool_write_ops: <{pool_write_ops_length}} \
|
||||||
pool_list_output.append('{bold}\
|
pool_list_output.append('{bold}\
|
||||||
{pool_id: <{pool_id_length}} \
|
{pool_id: <{pool_id_length}} \
|
||||||
{pool_name: <{pool_name_length}} \
|
{pool_name: <{pool_name_length}} \
|
||||||
{pool_size: <{pool_size_length}} \
|
{pool_used: <{pool_used_length}} \
|
||||||
|
{pool_usedpct: <{pool_usedpct_length}} \
|
||||||
|
{pool_free: <{pool_free_length}} \
|
||||||
{pool_objects: <{pool_objects_length}} \
|
{pool_objects: <{pool_objects_length}} \
|
||||||
{pool_clones: <{pool_clones_length}} \
|
{pool_clones: <{pool_clones_length}} \
|
||||||
{pool_copies: <{pool_copies_length}} \
|
{pool_copies: <{pool_copies_length}} \
|
||||||
|
@ -881,7 +909,9 @@ Wr: {pool_write_ops: <{pool_write_ops_length}} \
|
||||||
end_bold='',
|
end_bold='',
|
||||||
pool_id_length=pool_id_length,
|
pool_id_length=pool_id_length,
|
||||||
pool_name_length=pool_name_length,
|
pool_name_length=pool_name_length,
|
||||||
pool_size_length=pool_size_length,
|
pool_used_length=pool_used_length,
|
||||||
|
pool_usedpct_length=pool_usedpct_length,
|
||||||
|
pool_free_length=pool_free_length,
|
||||||
pool_objects_length=pool_num_objects_length,
|
pool_objects_length=pool_num_objects_length,
|
||||||
pool_clones_length=pool_num_clones_length,
|
pool_clones_length=pool_num_clones_length,
|
||||||
pool_copies_length=pool_num_copies_length,
|
pool_copies_length=pool_num_copies_length,
|
||||||
|
@ -892,7 +922,9 @@ Wr: {pool_write_ops: <{pool_write_ops_length}} \
|
||||||
pool_read_data_length=pool_read_data_length,
|
pool_read_data_length=pool_read_data_length,
|
||||||
pool_id=pool_information['stats']['id'],
|
pool_id=pool_information['stats']['id'],
|
||||||
pool_name=pool_information['name'],
|
pool_name=pool_information['name'],
|
||||||
pool_size=pool_information['stats']['size_bytes'],
|
pool_used=pool_information['stats']['used_bytes'],
|
||||||
|
pool_usedpct=pool_information['stats']['used_percent'],
|
||||||
|
pool_free=pool_information['stats']['free_bytes'],
|
||||||
pool_objects=pool_information['stats']['num_objects'],
|
pool_objects=pool_information['stats']['num_objects'],
|
||||||
pool_clones=pool_information['stats']['num_object_clones'],
|
pool_clones=pool_information['stats']['num_object_clones'],
|
||||||
pool_copies=pool_information['stats']['num_object_copies'],
|
pool_copies=pool_information['stats']['num_object_copies'],
|
||||||
|
|
|
@ -1009,21 +1009,42 @@ def update_zookeeper():
|
||||||
if this_node.router_state == 'primary':
|
if this_node.router_state == 'primary':
|
||||||
if debug:
|
if debug:
|
||||||
print("Set pool information in zookeeper (primary only)")
|
print("Set pool information in zookeeper (primary only)")
|
||||||
|
|
||||||
# Get pool info
|
# Get pool info
|
||||||
pool_df = dict()
|
retcode, stdout, stderr = common.run_os_command('ceph df --format json', timeout=1)
|
||||||
|
try:
|
||||||
|
ceph_pool_df_raw = json.loads(stdout)['pools']
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
logger.out('Failed to obtain Pool data (ceph df)', state='w')
|
||||||
|
ceph_pool_df_raw = []
|
||||||
|
|
||||||
retcode, stdout, stderr = common.run_os_command('rados df --format json', timeout=1)
|
retcode, stdout, stderr = common.run_os_command('rados df --format json', timeout=1)
|
||||||
try:
|
try:
|
||||||
pool_df_raw = json.loads(stdout)['pools']
|
rados_pool_df_raw = json.loads(stdout)['pools']
|
||||||
except json.decoder.JSONDecodeError:
|
except json.decoder.JSONDecodeError:
|
||||||
logger.out('Failed to obtain Pool data', state='w')
|
logger.out('Failed to obtain Pool data (rados df)', state='w')
|
||||||
pool_df_raw = []
|
rados_pool_df_raw = []
|
||||||
|
|
||||||
for pool in pool_df_raw:
|
pool_count = len(ceph_pool_df_raw)
|
||||||
pool_df.update({
|
for pool_idx in range(0, pool_count - 1):
|
||||||
str(pool['name']): {
|
try:
|
||||||
|
# Combine all the data for this pool
|
||||||
|
ceph_pool_df = ceph_pool_df_raw[pool_idx]
|
||||||
|
rados_pool_df = rados_pool_df_raw[pool_idx]
|
||||||
|
pool = ceph_pool_df
|
||||||
|
pool.update(rados_pool_df)
|
||||||
|
|
||||||
|
# Ignore any pools that aren't in our pool list
|
||||||
|
if pool['name'] not in pool_list:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Assemble a useful data structure
|
||||||
|
pool_df = {
|
||||||
'id': pool['id'],
|
'id': pool['id'],
|
||||||
'size_bytes': pool['size_bytes'],
|
'free_bytes': pool['stats']['max_avail'],
|
||||||
'num_objects': pool['num_objects'],
|
'used_bytes': pool['stats']['bytes_used'],
|
||||||
|
'used_percent': pool['stats']['percent_used'],
|
||||||
|
'num_objects': pool['stats']['objects'],
|
||||||
'num_object_clones': pool['num_object_clones'],
|
'num_object_clones': pool['num_object_clones'],
|
||||||
'num_object_copies': pool['num_object_copies'],
|
'num_object_copies': pool['num_object_copies'],
|
||||||
'num_objects_missing_on_primary': pool['num_objects_missing_on_primary'],
|
'num_objects_missing_on_primary': pool['num_objects_missing_on_primary'],
|
||||||
|
@ -1034,17 +1055,14 @@ def update_zookeeper():
|
||||||
'write_ops': pool['write_ops'],
|
'write_ops': pool['write_ops'],
|
||||||
'write_bytes': pool['write_bytes']
|
'write_bytes': pool['write_bytes']
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
# Trigger updates for each pool on this node
|
# Write the pool data to Zookeeper
|
||||||
for pool in pool_list:
|
|
||||||
try:
|
|
||||||
stats = json.dumps(pool_df[pool])
|
|
||||||
zkhandler.writedata(zk_conn, {
|
zkhandler.writedata(zk_conn, {
|
||||||
'/ceph/pools/{}/stats'.format(pool): str(stats)
|
'/ceph/pools/{}/stats'.format(pool['name']): str(json.dumps(pool_df))
|
||||||
})
|
})
|
||||||
except KeyError:
|
except Exception as e:
|
||||||
# One or more of the status commands timed out, just continue
|
# One or more of the status commands timed out, just continue
|
||||||
|
logger.out('Failed to format and send pool data', state='w')
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Only grab OSD stats if there are OSDs to grab (otherwise `ceph osd df` hangs)
|
# Only grab OSD stats if there are OSDs to grab (otherwise `ceph osd df` hangs)
|
||||||
|
|
Loading…
Reference in New Issue