diff --git a/README.md b/README.md index 2f94cb0d1..005051a12 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Nighthawk currently offers: - A load testing client which supports HTTP/1.1 and HTTP/2 over HTTP and HTTPS. (HTTPS certificates are not yet validated). - A simple [test server](source/server/README.md) which is capable of generating dynamic response sizes, as well as inject delays. - +- A binary to transform nighthawk output to well-known formats, allowing integration with other systems and dashboards. ## Prerequisites @@ -55,12 +55,13 @@ bazel-bin/nighthawk_client [--trace ] |CONNECT|OPTIONS|TRACE>] [--address-family ] [--burst-size ] [--prefetch-connections] [--output-format -] [-v ] [--concurrency -] [--h2] [--timeout ] -[--duration ] [--connections -] [--rps ] [--] -[--version] [-h] +] [-v ] +[--concurrency ] [--h2] [--timeout +] [--duration ] +[--connections ] [--rps +] [--] [--version] [-h] Where: @@ -111,9 +112,9 @@ Release requests in bursts of the specified size (default: 0). --prefetch-connections Prefetch connections before benchmarking (HTTP/1 only). ---output-format -Output format. Possible values: {"json", "human", "yaml", "dotted"}. -The default output format is 'human'. +--output-format +Output format. Possible values: {"json", "human", "yaml", "dotted", +"fortio"}. The default output format is 'human'. -v , --verbosity @@ -208,14 +209,15 @@ Nighthawk comes with a tool to transform its json output to its other supported USAGE: bazel-bin/nighthawk_output_transform --output-format [--] [--version] [-h] +|dotted|fortio> [--] [--version] +[-h] Where: ---output-format +--output-format (required) Output format. Possible values: {"json", "human", "yaml", -"dotted"}. +"dotted", "fortio"}. --, --ignore_rest Ignores the rest of the labeled arguments following this flag. @@ -305,6 +307,21 @@ client.upstream_rq_total 9994 1998.80 [21:28:18.522403][27849][I] [source/client/client.cc:279] Done. ``` +## Visualizing the output of a benchmark + +Nighthawk supports transforming the output into other well-known formats, such as: + +- `dotted`: Provides integration with Prometheus +- `fortio`: Provides integration with [Fortio's report-only UI](https://github.com/fortio/fortio#report-only-ui) + +The following is an example of a nighthawk benchmark visualized via the Fortio UI. + +```bash +fortio report --data-dir ./samples/fortio_data +``` + +![Fortio Large Report](./samples/fortio_reports/large.png) + ## Accuracy and repeatability considerations when using the Nighthawk client - Processes not related to the benchmarking task at hand may add significant noise. Consider stopping any diff --git a/api/client/options.proto b/api/client/options.proto index df41aeee0..947c97b3f 100644 --- a/api/client/options.proto +++ b/api/client/options.proto @@ -47,6 +47,7 @@ message OutputFormat { HUMAN = 2; YAML = 3; DOTTED = 4; + FORTIO = 5; } OutputFormatOptions value = 1; } diff --git a/api/client/transform/BUILD b/api/client/transform/BUILD new file mode 100644 index 000000000..dfa7f8a80 --- /dev/null +++ b/api/client/transform/BUILD @@ -0,0 +1,14 @@ +licenses(["notice"]) # Apache 2 + +load("@envoy//bazel:envoy_build_system.bzl", "envoy_package") +load("@envoy_api//bazel:api_build_system.bzl", "api_cc_py_proto_library") + +envoy_package() + +api_cc_py_proto_library( + name = "transform", + srcs = [ + "fortio.proto", + ], + visibility = ["//visibility:public"], +) diff --git a/api/client/transform/fortio.proto b/api/client/transform/fortio.proto new file mode 100644 index 000000000..3f312a6ba --- /dev/null +++ b/api/client/transform/fortio.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; + +package nighthawk.client; + +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; +import "validate/validate.proto"; + +// This proto represents that output format that Fortio expects when converted to JSON. +// Nighthawk can fill in this proto, and then unmarshal to the Fortio-compatible JSON. +// Therefore, this proto may not follow conventions. aip.dev/not-precedent +message FortioResult { + // Disable validate because it doesn't work well with fields that are not all lowercase. + // The field cases must match the final output JSON that fortio-ui expects. + option (validate.disabled) = true; + + string Labels = 1; + + google.protobuf.Timestamp StartTime = 2; + + uint32 RequestedQPS = 3; + + google.protobuf.Duration RequestedDuration = 4; + + double ActualQPS = 5; + + double ActualDuration = 6; + + uint32 NumThreads = 7; + + DurationHistogram DurationHistogram = 8; + + map RetCodes = 11; + + string URL = 12; +} + +message DurationHistogram { + option (validate.disabled) = true; + + uint64 Count = 1; + + repeated DataEntry Data = 2; +} + +message DataEntry { + option (validate.disabled) = true; + + double Start = 1; + + double End = 2; + + double Percent = 3; + + uint64 Count = 4; +} \ No newline at end of file diff --git a/samples/fortio_data/large.json b/samples/fortio_data/large.json new file mode 100644 index 000000000..83e1def5a --- /dev/null +++ b/samples/fortio_data/large.json @@ -0,0 +1,456 @@ +{ + "DurationHistogram": { + "Data": [ + { + "Start": 0.000135935, + "End": 0.000135935, + "Percent": 0, + "Count": "1" + }, + { + "Start": 0.000135935, + "End": 0.000159623, + "Percent": 10, + "Count": "1799" + }, + { + "Start": 0.000159623, + "End": 0.000164175, + "Percent": 20, + "Count": "1801" + }, + { + "Start": 0.000164175, + "End": 0.000169287, + "Percent": 30, + "Count": "1797" + }, + { + "Start": 0.000169287, + "End": 0.000175455, + "Percent": 40, + "Count": "1799" + }, + { + "Start": 0.000175455, + "End": 0.000182039, + "Percent": 50, + "Count": "1797" + }, + { + "Start": 0.000182039, + "End": 0.000186415, + "Percent": 55.000000000000007, + "Count": "901" + }, + { + "Start": 0.000186415, + "End": 0.000191287, + "Percent": 60, + "Count": "898" + }, + { + "Start": 0.000191287, + "End": 0.000199335, + "Percent": 65, + "Count": "900" + }, + { + "Start": 0.000199335, + "End": 0.000215383, + "Percent": 70, + "Count": "899" + }, + { + "Start": 0.000215383, + "End": 0.000251223, + "Percent": 75, + "Count": "899" + }, + { + "Start": 0.000251223, + "End": 0.000264639, + "Percent": 77.5, + "Count": "450" + }, + { + "Start": 0.000264639, + "End": 0.000275279, + "Percent": 80, + "Count": "451" + }, + { + "Start": 0.000275279, + "End": 0.000283023, + "Percent": 82.5, + "Count": "450" + }, + { + "Start": 0.000283023, + "End": 0.000291807, + "Percent": 85, + "Count": "448" + }, + { + "Start": 0.000291807, + "End": 0.000301919, + "Percent": 87.5, + "Count": "450" + }, + { + "Start": 0.000301919, + "End": 0.000307263, + "Percent": 88.75, + "Count": "226" + }, + { + "Start": 0.000307263, + "End": 0.000312623, + "Percent": 90, + "Count": "225" + }, + { + "Start": 0.000312623, + "End": 0.000317919, + "Percent": 91.25, + "Count": "224" + }, + { + "Start": 0.000317919, + "End": 0.000323439, + "Percent": 92.5, + "Count": "224" + }, + { + "Start": 0.000323439, + "End": 0.000329663, + "Percent": 93.75, + "Count": "225" + }, + { + "Start": 0.000329663, + "End": 0.000332815, + "Percent": 94.375, + "Count": "113" + }, + { + "Start": 0.000332815, + "End": 0.000336271, + "Percent": 95, + "Count": "112" + }, + { + "Start": 0.000336271, + "End": 0.000340639, + "Percent": 95.625, + "Count": "113" + }, + { + "Start": 0.000340639, + "End": 0.000345759, + "Percent": 96.25, + "Count": "112" + }, + { + "Start": 0.000345759, + "End": 0.000351743, + "Percent": 96.875, + "Count": "112" + }, + { + "Start": 0.000351743, + "End": 0.000355487, + "Percent": 97.1875, + "Count": "58" + }, + { + "Start": 0.000355487, + "End": 0.000359327, + "Percent": 97.5, + "Count": "55" + }, + { + "Start": 0.000359327, + "End": 0.000365935, + "Percent": 97.8125, + "Count": "56" + }, + { + "Start": 0.000365935, + "End": 0.000376511, + "Percent": 98.125, + "Count": "56" + }, + { + "Start": 0.000376511, + "End": 0.000394047, + "Percent": 98.4375, + "Count": "56" + }, + { + "Start": 0.000394047, + "End": 0.000408863, + "Percent": 98.59375, + "Count": "29" + }, + { + "Start": 0.000408863, + "End": 0.000435343, + "Percent": 98.75, + "Count": "28" + }, + { + "Start": 0.000435343, + "End": 0.000476383, + "Percent": 98.90625, + "Count": "28" + }, + { + "Start": 0.000476383, + "End": 0.000510767, + "Percent": 99.0625, + "Count": "28" + }, + { + "Start": 0.000510767, + "End": 0.000600095, + "Percent": 99.21875, + "Count": "28" + }, + { + "Start": 0.000600095, + "End": 0.000636383, + "Percent": 99.296875, + "Count": "14" + }, + { + "Start": 0.000636383, + "End": 0.000734591, + "Percent": 99.375, + "Count": "14" + }, + { + "Start": 0.000734591, + "End": 0.000990431, + "Percent": 99.453125, + "Count": "14" + }, + { + "Start": 0.000990431, + "End": 0.001162047, + "Percent": 99.53125, + "Count": "14" + }, + { + "Start": 0.001162047, + "End": 0.001317375, + "Percent": 99.609375, + "Count": "14" + }, + { + "Start": 0.001317375, + "End": 0.001459263, + "Percent": 99.6484375, + "Count": "7" + }, + { + "Start": 0.001459263, + "End": 0.001688191, + "Percent": 99.6875, + "Count": "7" + }, + { + "Start": 0.001688191, + "End": 0.002089407, + "Percent": 99.7265625, + "Count": "7" + }, + { + "Start": 0.002089407, + "End": 0.002495999, + "Percent": 99.765625, + "Count": "7" + }, + { + "Start": 0.002495999, + "End": 0.003138559, + "Percent": 99.8046875, + "Count": "7" + }, + { + "Start": 0.003138559, + "End": 0.003536767, + "Percent": 99.82421875, + "Count": "4" + }, + { + "Start": 0.003536767, + "End": 0.003691775, + "Percent": 99.84375, + "Count": "3" + }, + { + "Start": 0.003691775, + "End": 0.003963007, + "Percent": 99.86328125, + "Count": "4" + }, + { + "Start": 0.003963007, + "End": 0.004503551, + "Percent": 99.8828125, + "Count": "3" + }, + { + "Start": 0.004503551, + "End": 0.005279999, + "Percent": 99.90234375, + "Count": "4" + }, + { + "Start": 0.005279999, + "End": 0.006168831, + "Percent": 99.912109375, + "Count": "2" + }, + { + "Start": 0.006168831, + "End": 0.006596095, + "Percent": 99.921875, + "Count": "1" + }, + { + "Start": 0.006596095, + "End": 0.006909695, + "Percent": 99.931640625, + "Count": "2" + }, + { + "Start": 0.006909695, + "End": 0.007708159, + "Percent": 99.94140625, + "Count": "2" + }, + { + "Start": 0.007708159, + "End": 0.009518079, + "Percent": 99.951171875, + "Count": "2" + }, + { + "Start": 0.009518079, + "End": 0.010813951, + "Percent": 99.9560546875, + "Count": "1" + }, + { + "Start": 0.010813951, + "End": 0.010813951, + "Percent": 99.9609375, + "Count": "0" + }, + { + "Start": 0.010813951, + "End": 0.011096575, + "Percent": 99.9658203125, + "Count": "1" + }, + { + "Start": 0.011096575, + "End": 0.011655679, + "Percent": 99.970703125, + "Count": "1" + }, + { + "Start": 0.011655679, + "End": 0.011922943, + "Percent": 99.9755859375, + "Count": "1" + }, + { + "Start": 0.011922943, + "End": 0.013042687, + "Percent": 99.97802734375, + "Count": "1" + }, + { + "Start": 0.013042687, + "End": 0.013042687, + "Percent": 99.98046875, + "Count": "0" + }, + { + "Start": 0.013042687, + "End": 0.013042687, + "Percent": 99.98291015625, + "Count": "0" + }, + { + "Start": 0.013042687, + "End": 0.013305343, + "Percent": 99.9853515625, + "Count": "1" + }, + { + "Start": 0.013305343, + "End": 0.013305343, + "Percent": 99.98779296875, + "Count": "0" + }, + { + "Start": 0.013305343, + "End": 0.016256511, + "Percent": 99.989013671875, + "Count": "1" + }, + { + "Start": 0.016256511, + "End": 0.016256511, + "Percent": 99.990234375, + "Count": "0" + }, + { + "Start": 0.016256511, + "End": 0.016256511, + "Percent": 99.991455078125, + "Count": "0" + }, + { + "Start": 0.016256511, + "End": 0.016256511, + "Percent": 99.99267578125, + "Count": "0" + }, + { + "Start": 0.016256511, + "End": 0.016256511, + "Percent": 99.993896484375, + "Count": "0" + }, + { + "Start": 0.016256511, + "End": 0.019186687, + "Percent": 99.9945068359375, + "Count": "1" + }, + { + "Start": 0.019186687, + "End": 0.019186687, + "Percent": 100, + "Count": "0" + } + ], + "Count": "17988" + }, + "RetCodes": { + "200": "18000" + }, + "Labels": "A random label", + "StartTime": "2019-10-18T19:29:33Z", + "RequestedQPS": 50, + "RequestedDuration": "30s", + "ActualQPS": 50, + "ActualDuration": 30, + "NumThreads": 1, + "URL": "http://127.0.0.1:10001/" +} \ No newline at end of file diff --git a/samples/fortio_data/small.json b/samples/fortio_data/small.json new file mode 100644 index 000000000..6c0f6b963 --- /dev/null +++ b/samples/fortio_data/small.json @@ -0,0 +1,198 @@ +{ + "DurationHistogram": { + "Data": [ + { + "Start": 0.055568383, + "End": 0.056922111, + "Percent": 10, + "Count": "4" + }, + { + "Start": 0.056922111, + "End": 0.057884671, + "Percent": 20, + "Count": "5" + }, + { + "Start": 0.057884671, + "End": 0.059041791, + "Percent": 30, + "Count": "5" + }, + { + "Start": 0.059041791, + "End": 0.060086271, + "Percent": 40, + "Count": "5" + }, + { + "Start": 0.060086271, + "End": 0.060903423, + "Percent": 50, + "Count": "4" + }, + { + "Start": 0.060903423, + "End": 0.061583359, + "Percent": 55.000000000000007, + "Count": "3" + }, + { + "Start": 0.061583359, + "End": 0.061976575, + "Percent": 60, + "Count": "2" + }, + { + "Start": 0.061976575, + "End": 0.063830015, + "Percent": 65, + "Count": "3" + }, + { + "Start": 0.063830015, + "End": 0.064684031, + "Percent": 70, + "Count": "2" + }, + { + "Start": 0.064684031, + "End": 0.065679359, + "Percent": 75, + "Count": "2" + }, + { + "Start": 0.065679359, + "End": 0.066537471, + "Percent": 77.5, + "Count": "2" + }, + { + "Start": 0.066537471, + "End": 0.066994175, + "Percent": 80, + "Count": "1" + }, + { + "Start": 0.066994175, + "End": 0.067194879, + "Percent": 82.5, + "Count": "1" + }, + { + "Start": 0.067194879, + "End": 0.067563519, + "Percent": 85, + "Count": "1" + }, + { + "Start": 0.067563519, + "End": 0.067862527, + "Percent": 87.5, + "Count": "1" + }, + { + "Start": 0.067862527, + "End": 0.068161535, + "Percent": 88.75, + "Count": "1" + }, + { + "Start": 0.068161535, + "End": 0.068657151, + "Percent": 90, + "Count": "1" + }, + { + "Start": 0.068657151, + "End": 0.068657151, + "Percent": 91.25, + "Count": "0" + }, + { + "Start": 0.068657151, + "End": 0.069509119, + "Percent": 92.5, + "Count": "1" + }, + { + "Start": 0.069509119, + "End": 0.069509119, + "Percent": 93.75, + "Count": "0" + }, + { + "Start": 0.069509119, + "End": 0.073601023, + "Percent": 94.375, + "Count": "1" + }, + { + "Start": 0.073601023, + "End": 0.073601023, + "Percent": 95, + "Count": "0" + }, + { + "Start": 0.073601023, + "End": 0.073601023, + "Percent": 95.625, + "Count": "0" + }, + { + "Start": 0.073601023, + "End": 0.079327231, + "Percent": 96.25, + "Count": "1" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 96.875, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 97.1875, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 97.5, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 97.8125, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.084357119, + "Percent": 98.125, + "Count": "1" + }, + { + "Start": 0.084357119, + "End": 0.084357119, + "Percent": 100, + "Count": "0" + } + ], + "Count": "48" + }, + "RetCodes": { + "200": "60" + }, + "Labels": "A random label", + "StartTime": "2019-10-16T00:30:12Z", + "RequestedQPS": 1, + "RequestedDuration": "5s", + "ActualQPS": 1, + "ActualDuration": 5, + "NumThreads": 1, + "URL": "http://127.0.0.1:10000/" +} \ No newline at end of file diff --git a/samples/fortio_reports/large.png b/samples/fortio_reports/large.png new file mode 100644 index 000000000..dcf4262b8 Binary files /dev/null and b/samples/fortio_reports/large.png differ diff --git a/samples/fortio_reports/small.png b/samples/fortio_reports/small.png new file mode 100644 index 000000000..14e3bb8a5 Binary files /dev/null and b/samples/fortio_reports/small.png differ diff --git a/source/client/BUILD b/source/client/BUILD index 1a3bee48f..76ed15a80 100644 --- a/source/client/BUILD +++ b/source/client/BUILD @@ -115,6 +115,7 @@ envoy_cc_library( visibility = ["//visibility:public"], deps = [ "//api/client:base_cc_proto", + "//api/client/transform:transform_cc_proto", "//include/nighthawk/client:client_includes", "@envoy//source/common/network:utility_lib_with_external_headers", "@envoy//source/common/protobuf:utility_lib_with_external_headers", diff --git a/source/client/factories_impl.cc b/source/client/factories_impl.cc index e50eacc4d..142283b4d 100644 --- a/source/client/factories_impl.cc +++ b/source/client/factories_impl.cc @@ -3,6 +3,8 @@ #include "external/envoy/source/common/http/header_map_impl.h" #include "external/envoy/source/common/stats/isolated_store_impl.h" +#include "api/client/options.pb.h" + #include "common/header_source_impl.h" #include "common/platform_util_impl.h" #include "common/rate_limiter_impl.h" @@ -88,6 +90,8 @@ OutputFormatterPtr OutputFormatterFactoryImpl::create( return std::make_unique(); case nighthawk::client::OutputFormat::DOTTED: return std::make_unique(); + case nighthawk::client::OutputFormat::FORTIO: + return std::make_unique(); default: NOT_REACHED_GCOVR_EXCL_LINE; } diff --git a/source/client/output_formatter_impl.cc b/source/client/output_formatter_impl.cc index 5ad36b905..9d780d439 100644 --- a/source/client/output_formatter_impl.cc +++ b/source/client/output_formatter_impl.cc @@ -5,8 +5,14 @@ #include #include +#include "nighthawk/common/exception.h" + #include "external/envoy/source/common/protobuf/utility.h" +#include "api/client/transform/fortio.pb.h" + +#include "absl/strings/str_cat.h" + namespace Nighthawk { namespace Client { @@ -138,5 +144,125 @@ DottedStringOutputFormatterImpl::formatProto(const nighthawk::client::Output& ou return ss.str(); } +const nighthawk::client::Result& +FortioOutputFormatterImpl::getGlobalResult(const nighthawk::client::Output& output) const { + for (const auto& nh_result : output.results()) { + if (nh_result.name() == "global") { + return nh_result; + } + } + + throw NighthawkException("Nighthawk output was malformed, contains no 'global' results."); +} + +const nighthawk::client::Counter& +FortioOutputFormatterImpl::getCounterByName(const nighthawk::client::Result& result, + absl::string_view counter_name) const { + for (const auto& nh_counter : result.counters()) { + if (nh_counter.name() == counter_name) { + return nh_counter; + } + } + + throw NighthawkException(absl::StrCat( + "Nighthawk result was malformed, contains no counter with name: ", counter_name)); +} + +const nighthawk::client::Statistic& FortioOutputFormatterImpl::getRequestResponseStatistic( + const nighthawk::client::Result& result) const { + for (auto const& nh_stat : result.statistics()) { + if (nh_stat.id() == "benchmark_http_client.request_to_response") { + return nh_stat; + } + } + + throw NighthawkException("Nighthawk result was malformed, contains no " + "'benchmark_http_client.request_to_response' statistic."); +} + +std::string FortioOutputFormatterImpl::formatProto(const nighthawk::client::Output& output) const { + nighthawk::client::FortioResult fortio_output; + + // TODO(#182): Not needed but nice to have, displays in the UI + fortio_output.set_labels(""); + fortio_output.mutable_starttime()->set_seconds(output.timestamp().seconds()); + fortio_output.set_requestedqps(output.options().requests_per_second().value()); + fortio_output.set_url(output.options().uri().value()); + + // Actual and requested durations are the same + const auto& nh_duration = output.options().duration().seconds(); + fortio_output.mutable_requestedduration()->set_seconds(nh_duration); + fortio_output.set_actualduration(nh_duration); + + // This displays as "connections" in the UI, not threads. + // TODO(#186): This field may not be accurate for for HTTP2 load tests. + fortio_output.set_numthreads(output.options().connections().value()); + + // Get the result that represents all workers (global) + const auto& nh_global_result = this->getGlobalResult(output); + + // Fill in the actual QPS based on the counters + const auto& nh_rq_counter = this->getCounterByName(nh_global_result, "upstream_rq_total"); + const double actual_qps = static_cast(nh_rq_counter.value()) / nh_duration; + fortio_output.set_actualqps(actual_qps); + + // Fill in the number of successful responses. + // Fortio-ui only reads the 200 OK field, other fields are never displayed. + fortio_output.mutable_retcodes()->insert({"200", 0}); + try { + const auto& nh_2xx_counter = this->getCounterByName(nh_global_result, "benchmark.http_2xx"); + fortio_output.mutable_retcodes()->at("200") = nh_2xx_counter.value(); + } catch (const NighthawkException& e) { + // If this field doesn't exist, then there were no 2xx responses + fortio_output.mutable_retcodes()->at("200") = 0; + } + + // The core of the transformation is here: All the percentiles to display the dashboard + const auto& nh_stat = this->getRequestResponseStatistic(nh_global_result); + + // Set the count (number of data points) + nighthawk::client::DurationHistogram fortio_histogram; + fortio_histogram.set_count(nh_stat.count()); + + uint64_t prev_fortio_count = 0; + double prev_fortio_end = 0; + for (int i = 0; i < nh_stat.percentiles().size(); i++) { + + nighthawk::client::DataEntry fortio_data_entry; + const auto& nh_percentile = nh_stat.percentiles().at(i); + + // fortio_percent = 100 * nh_percentile + fortio_data_entry.set_percent(nh_percentile.percentile() * 100); + + // fortio_count = nh_count - prev_fortio_count + fortio_data_entry.set_count(nh_percentile.count() - prev_fortio_count); + + // fortio_end = nh_duration (need to convert formats) + const double nh_percentile_duration_sec = + Envoy::Protobuf::util::TimeUtil::DurationToNanoseconds(nh_percentile.duration()) / 1e9; + fortio_data_entry.set_end(nh_percentile_duration_sec); + + // fortio_start = prev_fortio_end + if (i == 0) { + // If this is the first entry, force the start and end time to be the same. + // This prevents it from starting at 0, making it disproportionally big in the UI. + prev_fortio_end = nh_percentile_duration_sec; + } + fortio_data_entry.set_start(prev_fortio_end); + + // Update tracking variables + prev_fortio_count = nh_percentile.count(); + prev_fortio_end = nh_percentile_duration_sec; + + // Set the data entry in the histogram only if it's not the first entry + fortio_histogram.add_data()->CopyFrom(fortio_data_entry); + } + + // Set the histogram in main fortio output + fortio_output.mutable_durationhistogram()->CopyFrom(fortio_histogram); + + return Envoy::MessageUtil::getJsonStringFromMessage(fortio_output, true, true); +} + } // namespace Client } // namespace Nighthawk \ No newline at end of file diff --git a/source/client/output_formatter_impl.h b/source/client/output_formatter_impl.h index 2ba6967eb..7e83ddfa8 100644 --- a/source/client/output_formatter_impl.h +++ b/source/client/output_formatter_impl.h @@ -8,6 +8,8 @@ #include "external/envoy/source/common/protobuf/protobuf.h" +#include "api/client/output.pb.h" + #include "absl/strings/string_view.h" namespace Nighthawk { @@ -47,5 +49,41 @@ class DottedStringOutputFormatterImpl : public OutputFormatterImpl { std::string formatProto(const nighthawk::client::Output& output) const override; }; +class FortioOutputFormatterImpl : public OutputFormatterImpl { +public: + std::string formatProto(const nighthawk::client::Output& output) const override; + +protected: + /** + * Return the result that represents all workers (the one with the "global" name). + * + * @param output the Nighthawk output proto + * @return the corresponding global result + * @throws NighthawkException if global result is not found + */ + const nighthawk::client::Result& getGlobalResult(const nighthawk::client::Output& output) const; + + /** + * Return the counter with the specified name. + * + * @param result a single Nighthawk result, preferably the global result + * @param counter_name the name of the counter to return + * @return the corresponding counter + * @throws NighthawkException if counter with given name is not found + */ + const nighthawk::client::Counter& getCounterByName(const nighthawk::client::Result& result, + absl::string_view counter_name) const; + + /** + * Return the statistic that represents the request/response round-trip times. + * + * @param result a single Nighthawk result, preferably the global result + * @return the corresponding request/response statistic + * @throws NighthawkException if request/response statistic is not found + */ + const nighthawk::client::Statistic& + getRequestResponseStatistic(const nighthawk::client::Result& result) const; +}; + } // namespace Client } // namespace Nighthawk \ No newline at end of file diff --git a/test/BUILD b/test/BUILD index f1f11246a..761dacb4b 100644 --- a/test/BUILD +++ b/test/BUILD @@ -104,6 +104,8 @@ envoy_cc_test( data = [ "test_data/output_formatter.dotted.gold", "test_data/output_formatter.json.gold", + "test_data/output_formatter.medium.fortio.gold", + "test_data/output_formatter.medium.proto.gold", "test_data/output_formatter.txt.gold", "test_data/output_formatter.yaml.gold", ], diff --git a/test/factories_test.cc b/test/factories_test.cc index 5eae116dd..aa9d34589 100644 --- a/test/factories_test.cc +++ b/test/factories_test.cc @@ -122,7 +122,8 @@ TEST_P(OutputFormatterFactoryTest, TestCreation) { testOutputCollector(GetParam( INSTANTIATE_TEST_SUITE_P( OutputFormats, OutputFormatterFactoryTest, ValuesIn({nighthawk::client::OutputFormat::HUMAN, nighthawk::client::OutputFormat::JSON, - nighthawk::client::OutputFormat::YAML, nighthawk::client::OutputFormat::DOTTED})); + nighthawk::client::OutputFormat::YAML, nighthawk::client::OutputFormat::DOTTED, + nighthawk::client::OutputFormat::FORTIO})); } // namespace Client } // namespace Nighthawk diff --git a/test/output_formatter_test.cc b/test/output_formatter_test.cc index cb96cebfd..c8b8a7edf 100644 --- a/test/output_formatter_test.cc +++ b/test/output_formatter_test.cc @@ -1,9 +1,13 @@ #include +#include "nighthawk/common/exception.h" + +#include "external/envoy/source/common/protobuf/message_validator_impl.h" #include "external/envoy/test/test_common/file_system_for_test.h" #include "external/envoy/test/test_common/simulated_time_system.h" #include "api/client/options.pb.h" +#include "api/client/output.pb.h" #include "common/statistic_impl.h" @@ -93,7 +97,74 @@ TEST_F(OutputCollectorTest, getLowerCaseOutputFormats) { auto output_formats = OutputFormatterImpl::getLowerCaseOutputFormats(); // When you're looking at this code you probably just added an output format. // This is to point out that you might want to update the list below and add a test above. - ASSERT_THAT(output_formats, ElementsAre("json", "human", "yaml", "dotted")); + ASSERT_THAT(output_formats, ElementsAre("json", "human", "yaml", "dotted", "fortio")); +} + +class FortioOutputCollectorTest : public OutputCollectorTest { +public: + FortioOutputCollectorTest() { + counters_["upstream_rq_total"] = 3; + counters_["benchmark.http_2xx"] = 4; + StatisticPtr used_statistic = std::make_unique(); + used_statistic->setId("benchmark_http_client.request_to_response"); + used_statistic->addValue(4000000); + statistics_.push_back(std::move(used_statistic)); + EXPECT_CALL(options_, toCommandLineOptions()) + .WillOnce(Return(ByMove( + std::make_unique(command_line_options_)))); + setupCollector(); + } +}; + +TEST_F(FortioOutputCollectorTest, MissingGlobalResult) { + nighthawk::client::Output output_proto = collector_->toProto(); + output_proto.clear_results(); + + FortioOutputFormatterImpl formatter; + ASSERT_THROW(formatter.formatProto(output_proto), NighthawkException); +} + +TEST_F(FortioOutputCollectorTest, MissingCounter) { + nighthawk::client::Output output_proto = collector_->toProto(); + output_proto.mutable_results(2)->clear_counters(); + + FortioOutputFormatterImpl formatter; + ASSERT_THROW(formatter.formatProto(output_proto), NighthawkException); +} + +TEST_F(FortioOutputCollectorTest, MissingStatistic) { + nighthawk::client::Output output_proto = collector_->toProto(); + output_proto.mutable_results(2)->clear_statistics(); + + FortioOutputFormatterImpl formatter; + ASSERT_THROW(formatter.formatProto(output_proto), NighthawkException); +} + +TEST_F(FortioOutputCollectorTest, NoExceptions) { + nighthawk::client::Output output_proto = collector_->toProto(); + + FortioOutputFormatterImpl formatter; + ASSERT_NO_THROW(formatter.formatProto(output_proto)); +} + +class MediumOutputCollectorTest : public OutputCollectorTest { +public: + nighthawk::client::Output loadProtoFromFile(absl::string_view path) { + nighthawk::client::Output proto; + const auto contents = Envoy::Filesystem::fileSystemForTest().fileReadToEnd( + TestEnvironment::runfilesPath(std::string(path))); + Envoy::MessageUtil::loadFromJson(contents, proto, + Envoy::ProtobufMessage::getStrictValidationVisitor()); + return proto; + } +}; + +TEST_F(MediumOutputCollectorTest, FortioFormatter) { + const auto input_proto = loadProtoFromFile("test/test_data/output_formatter.medium.proto.gold"); + + FortioOutputFormatterImpl formatter; + expectEqualToGoldFile(formatter.formatProto(input_proto), + "test/test_data/output_formatter.medium.fortio.gold"); } class StatidToNameTest : public Test {}; diff --git a/test/test_data/output_formatter.medium.fortio.gold b/test/test_data/output_formatter.medium.fortio.gold new file mode 100644 index 000000000..9d96dfdf3 --- /dev/null +++ b/test/test_data/output_formatter.medium.fortio.gold @@ -0,0 +1,204 @@ +{ + "Labels": "", + "RequestedQPS": 1, + "ActualQPS": 12, + "ActualDuration": 5, + "NumThreads": 1, + "DurationHistogram": { + "Count": "48", + "Data": [ + { + "Start": 0.055568383, + "End": 0.055568383, + "Percent": 0, + "Count": "1" + }, + { + "Start": 0.055568383, + "End": 0.056922111, + "Percent": 10, + "Count": "4" + }, + { + "Start": 0.056922111, + "End": 0.057884671, + "Percent": 20, + "Count": "5" + }, + { + "Start": 0.057884671, + "End": 0.059041791, + "Percent": 30, + "Count": "5" + }, + { + "Start": 0.059041791, + "End": 0.060086271, + "Percent": 40, + "Count": "5" + }, + { + "Start": 0.060086271, + "End": 0.060903423, + "Percent": 50, + "Count": "4" + }, + { + "Start": 0.060903423, + "End": 0.061583359, + "Percent": 55.000000000000007, + "Count": "3" + }, + { + "Start": 0.061583359, + "End": 0.061976575, + "Percent": 60, + "Count": "2" + }, + { + "Start": 0.061976575, + "End": 0.063830015, + "Percent": 65, + "Count": "3" + }, + { + "Start": 0.063830015, + "End": 0.064684031, + "Percent": 70, + "Count": "2" + }, + { + "Start": 0.064684031, + "End": 0.065679359, + "Percent": 75, + "Count": "2" + }, + { + "Start": 0.065679359, + "End": 0.066537471, + "Percent": 77.5, + "Count": "2" + }, + { + "Start": 0.066537471, + "End": 0.066994175, + "Percent": 80, + "Count": "1" + }, + { + "Start": 0.066994175, + "End": 0.067194879, + "Percent": 82.5, + "Count": "1" + }, + { + "Start": 0.067194879, + "End": 0.067563519, + "Percent": 85, + "Count": "1" + }, + { + "Start": 0.067563519, + "End": 0.067862527, + "Percent": 87.5, + "Count": "1" + }, + { + "Start": 0.067862527, + "End": 0.068161535, + "Percent": 88.75, + "Count": "1" + }, + { + "Start": 0.068161535, + "End": 0.068657151, + "Percent": 90, + "Count": "1" + }, + { + "Start": 0.068657151, + "End": 0.068657151, + "Percent": 91.25, + "Count": "0" + }, + { + "Start": 0.068657151, + "End": 0.069509119, + "Percent": 92.5, + "Count": "1" + }, + { + "Start": 0.069509119, + "End": 0.069509119, + "Percent": 93.75, + "Count": "0" + }, + { + "Start": 0.069509119, + "End": 0.073601023, + "Percent": 94.375, + "Count": "1" + }, + { + "Start": 0.073601023, + "End": 0.073601023, + "Percent": 95, + "Count": "0" + }, + { + "Start": 0.073601023, + "End": 0.073601023, + "Percent": 95.625, + "Count": "0" + }, + { + "Start": 0.073601023, + "End": 0.079327231, + "Percent": 96.25, + "Count": "1" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 96.875, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 97.1875, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 97.5, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.079327231, + "Percent": 97.8125, + "Count": "0" + }, + { + "Start": 0.079327231, + "End": 0.084357119, + "Percent": 98.125, + "Count": "1" + }, + { + "Start": 0.084357119, + "End": 0.084357119, + "Percent": 100, + "Count": "0" + } + ] + }, + "RetCodes": { + "200": "60" + }, + "URL": "http://127.0.0.1:10000/", + "StartTime": "2019-10-16T00:30:12Z", + "RequestedDuration": "5s" +} diff --git a/test/test_data/output_formatter.medium.proto.gold b/test/test_data/output_formatter.medium.proto.gold new file mode 100644 index 000000000..942f46aa3 --- /dev/null +++ b/test/test_data/output_formatter.medium.proto.gold @@ -0,0 +1,3522 @@ +{ + "options": { + "verbosity": { + "value": "INFO" + }, + "output_format": { + "value": "JSON" + }, + "address_family": { + "value": "AUTO" + }, + "request_options": { + "request_method": "GET", + "request_headers": [], + "request_body_size": 0 + }, + "tls_context": { + "sni": "", + "allow_renegotiation": false + }, + "sequencer_idle_strategy": { + "value": "SPIN" + }, + "requests_per_second": 1, + "connections": 1, + "duration": "5s", + "timeout": "30s", + "h2": false, + "concurrency": "auto", + "prefetch_connections": false, + "burst_size": 0, + "max_pending_requests": 1, + "max_active_requests": 4294937295, + "max_requests_per_connection": 4294937295, + "uri": "http://127.0.0.1:10000/", + "trace": "" + }, + "results": [ + { + "name": "worker_0", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000031494s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000031494s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000031494s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000032591s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000032591s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000032591s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000048189s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000048189s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000048189s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000048189s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000048189s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000117091s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000117091s" + } + ], + "mean": "0.000057341s", + "pstdev": "0.000035122s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.059297791s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.059297791s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.059297791s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.059312127s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.059312127s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.059312127s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.061976575s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.061976575s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.061976575s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.061976575s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.061976575s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.084357119s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.084357119s" + } + ], + "mean": "0.066234624s", + "pstdev": "0.010518547s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.059402239s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.059402239s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.059402239s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.059541503s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.059541503s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.059541503s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.062064639s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.062064639s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.062064639s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.062064639s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.062064639s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.084479999s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.084479999s" + } + ], + "mean": "0.066370816s", + "pstdev": "0.010507725s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_1", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000033313s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000033313s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000033313s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000035465s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000035465s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000035465s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000051897s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000051897s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000051897s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000051897s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000051897s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000070355s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000070355s" + } + ], + "mean": "0.000047757s", + "pstdev": "0.000014895s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.064684031s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.064684031s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.064684031s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.065081343s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.065081343s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.065081343s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.066537471s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.066537471s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.066537471s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.066537471s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.066537471s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.068657151s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.068657151s" + } + ], + "mean": "0.066238720s", + "pstdev": "0.001556413s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.064784383s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.064784383s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.064784383s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.065179647s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.065179647s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.065179647s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.066721791s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.066721791s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.066721791s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.066721791s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.066721791s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.068780031s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.068780031s" + } + ], + "mean": "0.066365184s", + "pstdev": "0.001569883s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_2", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000031796s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000031796s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000031796s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000040337s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000040337s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000040337s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000042679s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000042679s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000042679s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000042679s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000042679s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000053019s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000053019s" + } + ], + "mean": "0.000041958s", + "pstdev": "0.000007562s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.058099711s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.058099711s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.058099711s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.058902527s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.058902527s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.058902527s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.061583359s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.061583359s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.061583359s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.061583359s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.061583359s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.067194879s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.067194879s" + } + ], + "mean": "0.061443840s", + "pstdev": "0.003561025s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.058212351s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.058212351s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.058212351s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.059029503s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.059029503s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.059029503s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.061698047s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.061698047s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.061698047s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.061698047s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.061698047s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.067289087s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.067289087s" + } + ], + "mean": "0.061555968s", + "pstdev": "0.003551052s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_3", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000032588s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000032588s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000032588s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000040265s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000040265s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000040265s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000041157s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000041157s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000041157s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000041157s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000041157s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000043807s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000043807s" + } + ], + "mean": "0.000039454s", + "pstdev": "0.000004173s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.056578047s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.056578047s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.056578047s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.058265599s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.058265599s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.058265599s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.061620223s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.061620223s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.061620223s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.061620223s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.061620223s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.079327231s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.079327231s" + } + ], + "mean": "0.063946496s", + "pstdev": "0.009062473s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.056690687s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.056690687s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.056690687s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.058374143s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.058374143s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.058374143s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.061712383s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.061712383s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.061712383s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.061712383s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.061712383s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.079437823s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.079437823s" + } + ], + "mean": "0.064052480s", + "pstdev": "0.009063565s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_4", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000033859s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000033859s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000033859s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000035493s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000035493s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000035493s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000048117s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000048117s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000048117s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000048117s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000048117s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000051953s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000051953s" + } + ], + "mean": "0.000042356s", + "pstdev": "0.000007820s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.056150015s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.056150015s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.056150015s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.056334335s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.056334335s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.056334335s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.058064895s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.058064895s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.058064895s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.058064895s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.058064895s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.061089791s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.061089791s" + } + ], + "mean": "0.057908736s", + "pstdev": "0.001982128s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.056272895s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.056272895s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.056272895s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.056432639s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.056432639s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.056432639s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.058183679s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.058183679s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.058183679s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.058183679s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.058183679s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.061186047s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.061186047s" + } + ], + "mean": "0.058017792s", + "pstdev": "0.001976280s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_5", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000031978s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000031978s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000031978s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000035205s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000035205s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000035205s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000051767s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000051767s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000051767s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000051767s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000051767s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000054551s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000054551s" + } + ], + "mean": "0.000043375s", + "pstdev": "0.000009899s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057862143s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057862143s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057862143s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.063868927s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.063868927s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.063868927s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.065679359s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.065679359s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.065679359s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.065679359s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.065679359s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.067862527s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.067862527s" + } + ], + "mean": "0.063816960s", + "pstdev": "0.003717842s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057999359s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057999359s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057999359s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.063999999s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.063999999s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.063999999s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.065777663s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.065777663s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.065777663s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.065777663s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.065777663s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.067960831s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.067960831s" + } + ], + "mean": "0.063933184s", + "pstdev": "0.003702382s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_6", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000032893s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000032893s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000032893s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000033521s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000033521s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000033521s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000038597s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000038597s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000038597s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000038597s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000038597s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000039201s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000039201s" + } + ], + "mean": "0.000036053s", + "pstdev": "0.000002863s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.056922111s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.056922111s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.056922111s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.057616383s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.057616383s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.057616383s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.060835839s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.060835839s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.060835839s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.060835839s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.060835839s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.060927999s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.060927999s" + } + ], + "mean": "0.059074560s", + "pstdev": "0.001823229s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057012223s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057012223s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057012223s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.057716735s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.057716735s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.057716735s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.060936191s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.060936191s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.060936191s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.060936191s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.060936191s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.061034495s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.061034495s" + } + ], + "mean": "0.059173888s", + "pstdev": "0.001827817s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_7", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000031752s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000031752s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000031752s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000032747s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000032747s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000032747s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000044159s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000044159s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000044159s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000044159s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000044159s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000057509s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000057509s" + } + ], + "mean": "0.000041542s", + "pstdev": "0.000010428s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.055568383s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.055568383s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.055568383s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.059650047s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.059650047s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.059650047s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.067563519s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.067563519s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.067563519s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.067563519s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.067563519s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.069509119s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.069509119s" + } + ], + "mean": "0.063071232s", + "pstdev": "0.005692141s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.055662591s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.055662591s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.055662591s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.059742207s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.059742207s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.059742207s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.067682303s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.067682303s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.067682303s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.067682303s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.067682303s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.069631999s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.069631999s" + } + ], + "mean": "0.063178240s", + "pstdev": "0.005705402s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_8", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000031168s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000031168s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000031168s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000033925s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000033925s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000033925s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000037663s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000037663s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000037663s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000037663s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000037663s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000051237s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000051237s" + } + ], + "mean": "0.000038498s", + "pstdev": "0.000007707s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.056958975s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.056958975s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.056958975s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.059041791s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.059041791s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.059041791s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.060012543s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.060012543s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.060012543s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.060012543s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.060012543s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.063830015s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.063830015s" + } + ], + "mean": "0.059959808s", + "pstdev": "0.002491437s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057055231s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057055231s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057055231s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.059162623s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.059162623s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.059162623s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.060102655s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.060102655s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.060102655s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.060102655s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.060102655s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.063930367s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.063930367s" + } + ], + "mean": "0.060061696s", + "pstdev": "0.002490756s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_9", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000031853s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000031853s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000031853s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000035839s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000035839s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000035839s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000037101s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000037101s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000037101s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000037101s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000037101s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000042849s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000042849s" + } + ], + "mean": "0.000036911s", + "pstdev": "0.000003938s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057884671s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057884671s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057884671s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.060086271s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.060086271s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.060086271s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.062291967s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.062291967s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.062291967s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.062291967s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.062291967s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.068161535s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.068161535s" + } + ], + "mean": "0.062104832s", + "pstdev": "0.003827225s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057980927s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057980927s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057980927s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.060186623s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.060186623s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.060186623s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.062402559s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.062402559s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.062402559s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.062402559s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.062402559s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.068259839s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.068259839s" + } + ], + "mean": "0.062206208s", + "pstdev": "0.003827673s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_10", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000031242s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000031242s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000031242s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000035537s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000035537s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000035537s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000037795s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000037795s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000037795s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000037795s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000037795s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000051885s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000051885s" + } + ], + "mean": "0.000039115s", + "pstdev": "0.000007740s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057714687s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057714687s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057714687s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.060903423s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.060903423s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.060903423s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.065888255s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.065888255s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.065888255s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.065888255s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.065888255s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.073601023s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.073601023s" + } + ], + "mean": "0.064525568s", + "pstdev": "0.005993960s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.057802751s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.057802751s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.057802751s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.061003775s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.061003775s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.061003775s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.066009087s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.066009087s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.066009087s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.066009087s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.066009087s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.073703423s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.073703423s" + } + ], + "mean": "0.064628480s", + "pstdev": "0.005999399s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "worker_11", + "statistics": [ + { + "count": "4", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000029928s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.000029928s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.000029928s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.000032191s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.000032191s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.000032191s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.000034547s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.000034547s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.000034547s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.000034547s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.000034547s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.000041621s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.000041621s" + } + ], + "mean": "0.000034572s", + "pstdev": "0.000004385s" + }, + { + "count": "4", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.060487679s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.060487679s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.060487679s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.060641279s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.060641279s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.060641279s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.062892031s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.062892031s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.062892031s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.062892031s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.062892031s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.066994175s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.066994175s" + } + ], + "mean": "0.062752768s", + "pstdev": "0.002626687s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "4", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.060577791s" + }, + { + "percentile": 0.1, + "count": "1", + "duration": "0.060577791s" + }, + { + "percentile": 0.2, + "count": "1", + "duration": "0.060577791s" + }, + { + "percentile": 0.3, + "count": "2", + "duration": "0.060735487s" + }, + { + "percentile": 0.4, + "count": "2", + "duration": "0.060735487s" + }, + { + "percentile": 0.5, + "count": "2", + "duration": "0.060735487s" + }, + { + "percentile": 0.55, + "count": "3", + "duration": "0.062975999s" + }, + { + "percentile": 0.6, + "count": "3", + "duration": "0.062975999s" + }, + { + "percentile": 0.65, + "count": "3", + "duration": "0.062975999s" + }, + { + "percentile": 0.7, + "count": "3", + "duration": "0.062975999s" + }, + { + "percentile": 0.75, + "count": "3", + "duration": "0.062975999s" + }, + { + "percentile": 0.775, + "count": "4", + "duration": "0.067102719s" + }, + { + "percentile": 1, + "count": "4", + "duration": "0.067102719s" + } + ], + "mean": "0.062846976s", + "pstdev": "0.002633229s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "5" + } + ] + }, + { + "name": "global", + "statistics": [ + { + "count": "48", + "id": "benchmark_http_client.queue_to_connect", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.000029928s" + }, + { + "percentile": 0.1, + "count": "5", + "duration": "0.000031752s" + }, + { + "percentile": 0.2, + "count": "10", + "duration": "0.000032588s" + }, + { + "percentile": 0.3, + "count": "15", + "duration": "0.000033521s" + }, + { + "percentile": 0.4, + "count": "20", + "duration": "0.000035465s" + }, + { + "percentile": 0.5, + "count": "24", + "duration": "0.000037101s" + }, + { + "percentile": 0.55, + "count": "27", + "duration": "0.000038597s" + }, + { + "percentile": 0.6, + "count": "29", + "duration": "0.000040265s" + }, + { + "percentile": 0.65, + "count": "32", + "duration": "0.000041621s" + }, + { + "percentile": 0.7, + "count": "34", + "duration": "0.000042849s" + }, + { + "percentile": 0.75, + "count": "36", + "duration": "0.000044159s" + }, + { + "percentile": 0.775, + "count": "38", + "duration": "0.000048189s" + }, + { + "percentile": 0.8, + "count": "39", + "duration": "0.000051237s" + }, + { + "percentile": 0.825, + "count": "40", + "duration": "0.000051767s" + }, + { + "percentile": 0.85, + "count": "41", + "duration": "0.000051885s" + }, + { + "percentile": 0.875, + "count": "42", + "duration": "0.000051897s" + }, + { + "percentile": 0.8875, + "count": "43", + "duration": "0.000051953s" + }, + { + "percentile": 0.9, + "count": "44", + "duration": "0.000053019s" + }, + { + "percentile": 0.9125, + "count": "44", + "duration": "0.000053019s" + }, + { + "percentile": 0.925, + "count": "45", + "duration": "0.000054551s" + }, + { + "percentile": 0.9375, + "count": "45", + "duration": "0.000054551s" + }, + { + "percentile": 0.94375, + "count": "46", + "duration": "0.000057509s" + }, + { + "percentile": 0.95, + "count": "46", + "duration": "0.000057509s" + }, + { + "percentile": 0.95625, + "count": "46", + "duration": "0.000057509s" + }, + { + "percentile": 0.9625, + "count": "47", + "duration": "0.000070355s" + }, + { + "percentile": 0.96875, + "count": "47", + "duration": "0.000070355s" + }, + { + "percentile": 0.971875, + "count": "47", + "duration": "0.000070355s" + }, + { + "percentile": 0.975, + "count": "47", + "duration": "0.000070355s" + }, + { + "percentile": 0.978125, + "count": "47", + "duration": "0.000070355s" + }, + { + "percentile": 0.98125, + "count": "48", + "duration": "0.000117091s" + }, + { + "percentile": 1, + "count": "48", + "duration": "0.000117091s" + } + ], + "mean": "0.000041578s", + "pstdev": "0.000014060s" + }, + { + "count": "48", + "id": "benchmark_http_client.request_to_response", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.055568383s" + }, + { + "percentile": 0.1, + "count": "5", + "duration": "0.056922111s" + }, + { + "percentile": 0.2, + "count": "10", + "duration": "0.057884671s" + }, + { + "percentile": 0.3, + "count": "15", + "duration": "0.059041791s" + }, + { + "percentile": 0.4, + "count": "20", + "duration": "0.060086271s" + }, + { + "percentile": 0.5, + "count": "24", + "duration": "0.060903423s" + }, + { + "percentile": 0.55, + "count": "27", + "duration": "0.061583359s" + }, + { + "percentile": 0.6, + "count": "29", + "duration": "0.061976575s" + }, + { + "percentile": 0.65, + "count": "32", + "duration": "0.063830015s" + }, + { + "percentile": 0.7, + "count": "34", + "duration": "0.064684031s" + }, + { + "percentile": 0.75, + "count": "36", + "duration": "0.065679359s" + }, + { + "percentile": 0.775, + "count": "38", + "duration": "0.066537471s" + }, + { + "percentile": 0.8, + "count": "39", + "duration": "0.066994175s" + }, + { + "percentile": 0.825, + "count": "40", + "duration": "0.067194879s" + }, + { + "percentile": 0.85, + "count": "41", + "duration": "0.067563519s" + }, + { + "percentile": 0.875, + "count": "42", + "duration": "0.067862527s" + }, + { + "percentile": 0.8875, + "count": "43", + "duration": "0.068161535s" + }, + { + "percentile": 0.9, + "count": "44", + "duration": "0.068657151s" + }, + { + "percentile": 0.9125, + "count": "44", + "duration": "0.068657151s" + }, + { + "percentile": 0.925, + "count": "45", + "duration": "0.069509119s" + }, + { + "percentile": 0.9375, + "count": "45", + "duration": "0.069509119s" + }, + { + "percentile": 0.94375, + "count": "46", + "duration": "0.073601023s" + }, + { + "percentile": 0.95, + "count": "46", + "duration": "0.073601023s" + }, + { + "percentile": 0.95625, + "count": "46", + "duration": "0.073601023s" + }, + { + "percentile": 0.9625, + "count": "47", + "duration": "0.079327231s" + }, + { + "percentile": 0.96875, + "count": "47", + "duration": "0.079327231s" + }, + { + "percentile": 0.971875, + "count": "47", + "duration": "0.079327231s" + }, + { + "percentile": 0.975, + "count": "47", + "duration": "0.079327231s" + }, + { + "percentile": 0.978125, + "count": "47", + "duration": "0.079327231s" + }, + { + "percentile": 0.98125, + "count": "48", + "duration": "0.084357119s" + }, + { + "percentile": 1, + "count": "48", + "duration": "0.084357119s" + } + ], + "mean": "0.062589845s", + "pstdev": "0.005785869s" + }, + { + "count": "0", + "id": "sequencer.blocking", + "percentiles": [ + { + "percentile": 1, + "count": "0", + "duration": "0s" + } + ], + "mean": "0s", + "pstdev": "0s" + }, + { + "count": "48", + "id": "sequencer.callback", + "percentiles": [ + { + "percentile": 0, + "count": "1", + "duration": "0.055662591s" + }, + { + "percentile": 0.1, + "count": "5", + "duration": "0.057012223s" + }, + { + "percentile": 0.2, + "count": "10", + "duration": "0.057999359s" + }, + { + "percentile": 0.3, + "count": "15", + "duration": "0.059162623s" + }, + { + "percentile": 0.4, + "count": "20", + "duration": "0.060186623s" + }, + { + "percentile": 0.5, + "count": "24", + "duration": "0.061003775s" + }, + { + "percentile": 0.55, + "count": "27", + "duration": "0.061698047s" + }, + { + "percentile": 0.6, + "count": "29", + "duration": "0.062064639s" + }, + { + "percentile": 0.65, + "count": "32", + "duration": "0.063930367s" + }, + { + "percentile": 0.7, + "count": "34", + "duration": "0.064784383s" + }, + { + "percentile": 0.75, + "count": "36", + "duration": "0.065777663s" + }, + { + "percentile": 0.775, + "count": "38", + "duration": "0.066721791s" + }, + { + "percentile": 0.8, + "count": "39", + "duration": "0.067102719s" + }, + { + "percentile": 0.825, + "count": "40", + "duration": "0.067289087s" + }, + { + "percentile": 0.85, + "count": "41", + "duration": "0.067682303s" + }, + { + "percentile": 0.875, + "count": "42", + "duration": "0.067960831s" + }, + { + "percentile": 0.8875, + "count": "43", + "duration": "0.068259839s" + }, + { + "percentile": 0.9, + "count": "44", + "duration": "0.068780031s" + }, + { + "percentile": 0.9125, + "count": "44", + "duration": "0.068780031s" + }, + { + "percentile": 0.925, + "count": "45", + "duration": "0.069631999s" + }, + { + "percentile": 0.9375, + "count": "45", + "duration": "0.069631999s" + }, + { + "percentile": 0.94375, + "count": "46", + "duration": "0.073703423s" + }, + { + "percentile": 0.95, + "count": "46", + "duration": "0.073703423s" + }, + { + "percentile": 0.95625, + "count": "46", + "duration": "0.073703423s" + }, + { + "percentile": 0.9625, + "count": "47", + "duration": "0.079437823s" + }, + { + "percentile": 0.96875, + "count": "47", + "duration": "0.079437823s" + }, + { + "percentile": 0.971875, + "count": "47", + "duration": "0.079437823s" + }, + { + "percentile": 0.975, + "count": "47", + "duration": "0.079437823s" + }, + { + "percentile": 0.978125, + "count": "47", + "duration": "0.079437823s" + }, + { + "percentile": 0.98125, + "count": "48", + "duration": "0.084479999s" + }, + { + "percentile": 1, + "count": "48", + "duration": "0.084479999s" + } + ], + "mean": "0.062699243s", + "pstdev": "0.005788063s" + } + ], + "counters": [ + { + "name": "benchmark.http_2xx", + "value": "60" + }, + { + "name": "cluster_manager.cluster_added", + "value": "12" + }, + { + "name": "default.total_match_count", + "value": "12" + }, + { + "name": "membership_change", + "value": "12" + }, + { + "name": "runtime.load_success", + "value": "1" + }, + { + "name": "runtime.override_dir_not_exists", + "value": "1" + }, + { + "name": "upstream_cx_destroy", + "value": "12" + }, + { + "name": "upstream_cx_destroy_local", + "value": "12" + }, + { + "name": "upstream_cx_http1_total", + "value": "12" + }, + { + "name": "upstream_cx_rx_bytes_total", + "value": "3338276" + }, + { + "name": "upstream_cx_total", + "value": "12" + }, + { + "name": "upstream_cx_tx_bytes_total", + "value": "3600" + }, + { + "name": "upstream_rq_pending_total", + "value": "12" + }, + { + "name": "upstream_rq_total", + "value": "60" + } + ] + } + ], + "timestamp": "2019-10-16T00:30:12.911078318Z" +}