diff --git a/mon/mon.js b/mon/mon.js index 36c94296..eb892989 100644 --- a/mon/mon.js +++ b/mon/mon.js @@ -34,7 +34,7 @@ const etcd_allow = new RegExp('^'+[ 'pg/stats/[1-9]\\d*/[1-9]\\d*', 'pg/history/[1-9]\\d*/[1-9]\\d*', 'history/last_clean_pgs', - 'inode/stats/[1-9]\\d*', + 'inode/stats/[1-9]\\d*/[1-9]\\d*', 'stats', ].join('$|^')+'$'); @@ -1178,23 +1178,31 @@ class Mon }); for (const osd_num in this.state.osd.space) { - for (const inode_num in this.state.osd.space[osd_num]) + for (const pool_id in this.state.osd.space[osd_num]) { - inode_stats[inode_num] = inode_stats[inode_num] || inode_stub(); - inode_stats[inode_num].raw_used += BigInt(this.state.osd.space[osd_num][inode_num]||0); + inode_stats[pool_id] = inode_stats[pool_id] || {}; + for (const inode_num in this.state.osd.space[osd_num][pool_id]) + { + inode_stats[pool_id][inode_num] = inode_stats[pool_id][inode_num] || inode_stub(); + inode_stats[pool_id][inode_num].raw_used += BigInt(this.state.osd.space[osd_num][pool_id][inode_num]||0); + } } } for (const osd_num in this.state.osd.inodestats) { const ist = this.state.osd.inodestats[osd_num]; - for (const inode_num in ist) + for (const pool_id in ist) { - inode_stats[inode_num] = inode_stats[inode_num] || inode_stub(); - for (const op of [ 'read', 'write', 'delete' ]) + inode_stats[pool_id] = inode_stats[pool_id] || {}; + for (const inode_num in ist[pool_id]) { - inode_stats[inode_num][op].count += BigInt(ist[inode_num][op].count||0); - inode_stats[inode_num][op].usec += BigInt(ist[inode_num][op].usec||0); - inode_stats[inode_num][op].bytes += BigInt(ist[inode_num][op].bytes||0); + inode_stats[pool_id][inode_num] = inode_stats[pool_id][inode_num] || inode_stub(); + for (const op of [ 'read', 'write', 'delete' ]) + { + inode_stats[pool_id][inode_num][op].count += BigInt(ist[pool_id][inode_num][op].count||0); + inode_stats[pool_id][inode_num][op].usec += BigInt(ist[pool_id][inode_num][op].usec||0); + inode_stats[pool_id][inode_num][op].bytes += BigInt(ist[pool_id][inode_num][op].bytes||0); + } } } } @@ -1260,12 +1268,15 @@ class Mon this.serialize_bigints(stats); this.serialize_bigints(inode_stats); txn.push({ requestPut: { key: b64(this.etcd_prefix+'/stats'), value: b64(JSON.stringify(stats)) } }); - for (const inode_num in inode_stats) + for (const pool_id in inode_stats) { - txn.push({ requestPut: { - key: b64(this.etcd_prefix+'/inode/stats/'+inode_num), - value: b64(JSON.stringify(inode_stats[inode_num])), - } }); + for (const inode_num in inode_stats[pool_id]) + { + txn.push({ requestPut: { + key: b64(this.etcd_prefix+'/inode/stats/'+pool_id+'/'+inode_num), + value: b64(JSON.stringify(inode_stats[pool_id][inode_num])), + } }); + } } if (txn.length) { diff --git a/src/osd_cluster.cpp b/src/osd_cluster.cpp index a2fc4c8f..7fc5500f 100644 --- a/src/osd_cluster.cpp +++ b/src/osd_cluster.cpp @@ -183,14 +183,38 @@ void osd_t::report_statistics() // Report space usage statistics as a whole // Maybe we'll report it using deltas if we tune for a lot of inodes at some point json11::Json::object inode_space; + json11::Json::object last_stat; + pool_id_t last_pool = 0; for (auto kv: bs->get_inode_space_stats()) { - inode_space[std::to_string(kv.first)] = kv.second; + pool_id_t pool_id = INODE_POOL(kv.first); + uint64_t only_inode_num = (kv.first & ((1l << (64-POOL_ID_BITS)) - 1)); + if (!last_pool || pool_id != last_pool) + { + if (last_pool) + inode_space[std::to_string(last_pool)] = last_stat; + last_stat = json11::Json::object(); + last_pool = pool_id; + } + last_stat[std::to_string(only_inode_num)] = kv.second; } + if (last_pool) + inode_space[std::to_string(last_pool)] = last_stat; + last_stat = json11::Json::object(); + last_pool = 0; json11::Json::object inode_ops; for (auto kv: inode_stats) { - inode_ops[std::to_string(kv.first)] = json11::Json::object { + pool_id_t pool_id = INODE_POOL(kv.first); + uint64_t only_inode_num = (kv.first & ((1l << (64-POOL_ID_BITS)) - 1)); + if (!last_pool || pool_id != last_pool) + { + if (last_pool) + inode_ops[std::to_string(last_pool)] = last_stat; + last_stat = json11::Json::object(); + last_pool = pool_id; + } + last_stat[std::to_string(only_inode_num)] = json11::Json::object { { "read", json11::Json::object { { "count", kv.second.op_count[INODE_STATS_READ] }, { "usec", kv.second.op_sum[INODE_STATS_READ] }, @@ -208,20 +232,28 @@ void osd_t::report_statistics() } }, }; } - json11::Json::array txn = { json11::Json::object { - { "request_put", json11::Json::object { - { "key", base64_encode(st_cli.etcd_prefix+"/osd/stats/"+std::to_string(osd_num)) }, - { "value", base64_encode(get_statistics().dump()) }, - } }, - { "request_put", json11::Json::object { - { "key", base64_encode(st_cli.etcd_prefix+"/osd/space/"+std::to_string(osd_num)) }, - { "value", base64_encode(json11::Json(inode_space).dump()) }, - } }, - { "request_put", json11::Json::object { - { "key", base64_encode(st_cli.etcd_prefix+"/osd/inodestats/"+std::to_string(osd_num)) }, - { "value", base64_encode(json11::Json(inode_ops).dump()) }, - } }, - } }; + if (last_pool) + inode_ops[std::to_string(last_pool)] = last_stat; + json11::Json::array txn = { + json11::Json::object { + { "request_put", json11::Json::object { + { "key", base64_encode(st_cli.etcd_prefix+"/osd/stats/"+std::to_string(osd_num)) }, + { "value", base64_encode(get_statistics().dump()) }, + } }, + }, + json11::Json::object { + { "request_put", json11::Json::object { + { "key", base64_encode(st_cli.etcd_prefix+"/osd/space/"+std::to_string(osd_num)) }, + { "value", base64_encode(json11::Json(inode_space).dump()) }, + } }, + }, + json11::Json::object { + { "request_put", json11::Json::object { + { "key", base64_encode(st_cli.etcd_prefix+"/osd/inodestats/"+std::to_string(osd_num)) }, + { "value", base64_encode(json11::Json(inode_ops).dump()) }, + } }, + }, + }; for (auto & p: pgs) { auto & pg = p.second;