diff --git a/utils/keeper-bench/Runner.cpp b/utils/keeper-bench/Runner.cpp index 4250263f043..bb8ff46a20c 100644 --- a/utils/keeper-bench/Runner.cpp +++ b/utils/keeper-bench/Runner.cpp @@ -5,7 +5,10 @@ #include "Common/ZooKeeper/ZooKeeperConstants.h" #include #include -#include "IO/WriteBufferFromFile.h" +#include "IO/ReadBufferFromString.h" +#include +#include +#include namespace CurrentMetrics { @@ -82,6 +85,25 @@ Runner::Runner( else continue_on_error = config->getBool("continue_on_error", false); std::cerr << "Continue on error: " << continue_on_error << std::endl; + + static const std::string output_key = "output"; + print_to_stdout = config->getBool(output_key + ".stdout", false); + std::cerr << "Printing output to stdout: " << print_to_stdout << std::endl; + + static const std::string output_file_key = output_key + ".file"; + if (config->has(output_file_key)) + { + if (config->has(output_file_key + ".path")) + { + file_output = config->getString(output_file_key + ".path"); + output_file_with_timestamp = config->getBool(output_file_key + ".with_timestamp"); + } + else + file_output = config->getString(output_file_key); + + std::cerr << "Result file path: " << file_output->string() << std::endl; + } + std::cerr << "---- Run options ----\n" << std::endl; pool.emplace(CurrentMetrics::LocalThread, CurrentMetrics::LocalThreadActive, concurrency); @@ -261,24 +283,6 @@ void Runner::thread(std::vector> zookee bool Runner::tryPushRequestInteractively(Coordination::ZooKeeperRequestPtr && request, DB::InterruptListener & interrupt_listener) { - //static std::unordered_map counts; - //static size_t i = 0; - // - //counts[request->getOpNum()]++; - - //if (request->getOpNum() == Coordination::OpNum::Multi) - //{ - // for (const auto & multi_request : dynamic_cast(*request).requests) - // counts[dynamic_cast(*multi_request).getOpNum()]++; - //} - - //++i; - //if (i % 10000 == 0) - //{ - // for (const auto & [op_num, count] : counts) - // std::cerr << fmt::format("{}: {}", op_num, count) << std::endl; - //} - bool inserted = false; while (!inserted) @@ -324,6 +328,9 @@ void Runner::runBenchmark() std::cerr << "Preparing to run\n"; generator->startup(*connections[0]); std::cerr << "Prepared\n"; + + auto start_timestamp_ms = Poco::Timestamp{}.epochMicroseconds() / 1000; + try { for (size_t i = 0; i < concurrency; ++i) @@ -360,8 +367,30 @@ void Runner::runBenchmark() std::lock_guard lock(mutex); info->report(concurrency); - DB::WriteBufferFromFile out("result.json"); - info->writeJSON(out, concurrency); + DB::WriteBufferFromOwnString out; + info->writeJSON(out, concurrency, start_timestamp_ms); + auto output_string = std::move(out.str()); + + if (print_to_stdout) + std::cout << output_string << std::endl; + + if (file_output) + { + auto path = *file_output; + + if (output_file_with_timestamp) + { + auto filename = file_output->filename(); + filename = fmt::format("{}_{}{}", filename.stem().generic_string(), start_timestamp_ms, filename.extension().generic_string()); + path = file_output->parent_path() / filename; + } + + std::cerr << "Storing output to " << path << std::endl; + + DB::WriteBufferFromFile file_output_buffer(path); + DB::ReadBufferFromString read_buffer(output_string); + DB::copyData(read_buffer, file_output_buffer); + } } diff --git a/utils/keeper-bench/Runner.h b/utils/keeper-bench/Runner.h index 7f41958a45a..f899f1d538d 100644 --- a/utils/keeper-bench/Runner.h +++ b/utils/keeper-bench/Runner.h @@ -7,8 +7,6 @@ #include #include #include -#include -#include #include #include @@ -16,6 +14,8 @@ #include #include "Stats.h" +#include + using Ports = std::vector; using Strings = std::vector; @@ -59,6 +59,9 @@ private: std::atomic shutdown = false; std::shared_ptr info; + bool print_to_stdout; + std::optional file_output; + bool output_file_with_timestamp; Stopwatch total_watch; Stopwatch delay_watch; diff --git a/utils/keeper-bench/Stats.cpp b/utils/keeper-bench/Stats.cpp index 21de72f6047..f5e5f84ba14 100644 --- a/utils/keeper-bench/Stats.cpp +++ b/utils/keeper-bench/Stats.cpp @@ -119,17 +119,21 @@ void Stats::report(size_t concurrency) } } -void Stats::writeJSON(DB::WriteBuffer & out, size_t concurrency) +void Stats::writeJSON(DB::WriteBuffer & out, size_t concurrency, int64_t start_timestamp) { using namespace rapidjson; Document results; auto & allocator = results.GetAllocator(); results.SetObject(); + results.AddMember("timestamp", Value(start_timestamp), allocator); + const auto get_results = [&](auto & collector) { Value specific_results(kObjectType); + specific_results.AddMember("total_requests", Value(collector.requests), allocator); + auto [rps, bps] = collector.getThroughput(concurrency); specific_results.AddMember("requests_per_second", Value(rps), allocator); specific_results.AddMember("bytes_per_second", Value(bps), allocator); @@ -139,9 +143,8 @@ void Stats::writeJSON(DB::WriteBuffer & out, size_t concurrency) const auto add_percentile = [&](double percent) { Value percentile(kObjectType); - percentile.AddMember("percentile", Value(percent), allocator); - percentile.AddMember("value", Value(collector.getPercentile(percent)), allocator); - + Value percent_key(fmt::format("{:.2f}", percent).c_str(), allocator); + percentile.AddMember(percent_key, Value(collector.getPercentile(percent)), allocator); percentiles.PushBack(percentile, allocator); }; diff --git a/utils/keeper-bench/Stats.h b/utils/keeper-bench/Stats.h index 7afd8ce4f1a..bc50588e837 100644 --- a/utils/keeper-bench/Stats.h +++ b/utils/keeper-bench/Stats.h @@ -36,7 +36,7 @@ struct Stats void clear(); void report(size_t concurrency); - void writeJSON(DB::WriteBuffer & out, size_t concurrency); + void writeJSON(DB::WriteBuffer & out, size_t concurrency, int64_t start_timestamp); }; diff --git a/utils/keeper-bench/example.yaml b/utils/keeper-bench/example.yaml index 2febb881634..e800e923482 100644 --- a/utils/keeper-bench/example.yaml +++ b/utils/keeper-bench/example.yaml @@ -109,3 +109,9 @@ generator: - "/test4" path: children_of: "/test" + +output: + file: + path: "output.json" + with_timestamp: true + stdout: true