diff --git a/src/tools/cephfs/cephfs-tool.cc b/src/tools/cephfs/cephfs-tool.cc index 29b4d9310af..9762dfc0849 100644 --- a/src/tools/cephfs/cephfs-tool.cc +++ b/src/tools/cephfs/cephfs-tool.cc @@ -31,6 +31,9 @@ #include #include "common/JSONFormatter.h" +#include "common/ceph_context.h" +#include "common/cmdparse.h" +#include "common/perf_counters_collection.h" // Standard Public Ceph API #include @@ -40,6 +43,8 @@ // Boost Program Options #include +#include "cls/journal/cls_journal_types.h" + using std::cerr; using std::cout; using std::endl; @@ -161,6 +166,7 @@ struct BenchConfig { int gid; string json_path; int duration; + string perf_dump_path; }; struct ThreadStats { @@ -472,6 +478,35 @@ bench_read_worker( } } +void +execute_perf_dump(struct ceph_mount_info* cmount, const string& output_path) +{ + if (output_path.empty()) { + return; + } + + char* perf_dump = nullptr; + int rc = ceph_get_perf_counters(cmount, &perf_dump); + if (rc < 0) { + cerr << "Error: Failed to get performance counters: " << strerror(-rc) + << endl; + return; + } + + if (perf_dump) { + std::ofstream ofs(output_path); + if (!ofs.is_open()) { + cerr << "Error: Could not open " << output_path + << " for writing performance counters." << endl; + free(perf_dump); + return; + } + ofs << perf_dump; + free(perf_dump); + cout << "Performance counters dumped to " << output_path << endl; + } +} + // Worker function for Cleanup (Unlink) phase void bench_cleanup_worker(int thread_id, int files_to_clean, @@ -863,9 +898,15 @@ int do_bench(BenchConfig& config) { } } + if (!config.perf_dump_path.empty()) { + execute_perf_dump(shared_cmount, config.perf_dump_path); + } + if (int rc = ceph_unmount(shared_cmount); rc < 0) { cerr << "Final unmount failed: " << strerror(-rc) << endl; } + + ceph_shutdown(shared_cmount); return 0; } @@ -902,7 +943,8 @@ int main(int argc, char **argv) { ("per-thread-mount", po::bool_switch(&config.per_thread_mount), "Use separate mount per thread") ("no-cleanup", po::bool_switch(&no_cleanup), "Disable cleanup of files") ("json", po::value(&config.json_path), "Output results to a JSON file") - ("duration", po::value(&config.duration)->default_value(0), "Limit each phase to N seconds (0 = no limit)"); + ("duration", po::value(&config.duration)->default_value(0), "Limit each phase to N seconds (0 = no limit)") + ("perf-dump", po::value(&config.perf_dump_path), "File to dump performance counters to"); // Hidden positional option for the sub-command po::options_description hidden("Hidden options");