diff --git a/internal_proto/README.md b/internal_proto/README.md new file mode 100644 index 000000000..3e8495d79 --- /dev/null +++ b/internal_proto/README.md @@ -0,0 +1,3 @@ +# Internal proto definitions + +Warning: this directory contains proto defininitions which are used internally by Nighthawk, and are subject to change. diff --git a/internal_proto/statistic/BUILD b/internal_proto/statistic/BUILD new file mode 100644 index 000000000..8a86d4361 --- /dev/null +++ b/internal_proto/statistic/BUILD @@ -0,0 +1,11 @@ +load("@envoy_api//bazel:api_build_system.bzl", "api_cc_py_proto_library") + +licenses(["notice"]) # Apache 2 + +api_cc_py_proto_library( + name = "statistic", + srcs = [ + "statistic.proto", + ], + visibility = ["//visibility:public"], +) diff --git a/internal_proto/statistic/statistic.proto b/internal_proto/statistic/statistic.proto new file mode 100644 index 000000000..4db664e24 --- /dev/null +++ b/internal_proto/statistic/statistic.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package nighthawk.internal; + +// This package contains proto definitions which allow serialization / deserialization +// of statistics implementations. Naming maps 1:1 with the statistics implementations +// over at source/common/statistics_impl.h. See the code & doc comments there for further +// information about the corresponding statistics implementations. + +message SimpleStatistic { + uint64 count = 1; + string id = 2; + uint64 min = 5; + uint64 max = 6; + double sum_x = 7; + double sum_x_2 = 8; +} + +message StreamingStatistic { + uint64 count = 1; + string id = 2; + uint64 min = 5; + uint64 max = 6; + double mean = 7; + double accumulated_variance = 8; +} diff --git a/source/common/BUILD b/source/common/BUILD index 951c2a411..3df97e2bd 100644 --- a/source/common/BUILD +++ b/source/common/BUILD @@ -146,6 +146,7 @@ envoy_cc_library( "//api/client:grpc_service_lib", "//include/nighthawk/client:client_includes", "//include/nighthawk/common:base_includes", + "//internal_proto/statistic:statistic_cc_proto", "@com_google_absl//absl/random", "@com_google_absl//absl/strings", "@dep_hdrhistogram_c//:hdrhistogram_c", diff --git a/source/common/statistic_impl.cc b/source/common/statistic_impl.cc index 1a0067066..e44eb999c 100644 --- a/source/common/statistic_impl.cc +++ b/source/common/statistic_impl.cc @@ -9,6 +9,8 @@ #include "external/envoy/source/common/common/assert.h" #include "external/envoy/source/common/protobuf/utility.h" +#include "internal_proto/statistic/statistic.pb.h" + namespace Nighthawk { namespace { @@ -104,6 +106,38 @@ StatisticPtr SimpleStatistic::combine(const Statistic& statistic) const { return combined; } +absl::StatusOr> SimpleStatistic::serializeNative() const { + nighthawk::internal::SimpleStatistic proto; + proto.set_id(id()); + proto.set_count(count()); + proto.set_min(min()); + proto.set_max(max()); + proto.set_sum_x(sum_x_); + proto.set_sum_x_2(sum_x2_); + + std::string tmp; + proto.SerializeToString(&tmp); + auto write_stream = std::make_unique(); + *write_stream << tmp; + return write_stream; +} + +absl::Status SimpleStatistic::deserializeNative(std::istream& stream) { + nighthawk::internal::SimpleStatistic proto; + std::string tmp(std::istreambuf_iterator(stream), {}); + if (!proto.ParseFromString(tmp)) { + ENVOY_LOG(error, "Failed to read back SimpleStatistic data."); + return absl::Status(absl::StatusCode::kInternal, "Failed to read back SimpleStatistic data"); + } + id_ = proto.id(); + count_ = proto.count(); + min_ = proto.min(); + max_ = proto.max(); + sum_x_ = proto.sum_x(); + sum_x2_ = proto.sum_x_2(); + return absl::OkStatus(); +} + void StreamingStatistic::addValue(uint64_t value) { double delta, delta_n; StatisticImpl::addValue(value); @@ -142,6 +176,38 @@ StatisticPtr StreamingStatistic::combine(const Statistic& statistic) const { return combined; } +absl::StatusOr> StreamingStatistic::serializeNative() const { + nighthawk::internal::StreamingStatistic proto; + proto.set_id(id()); + proto.set_count(count()); + proto.set_min(min()); + proto.set_max(max()); + proto.set_mean(mean_); + proto.set_accumulated_variance(accumulated_variance_); + + std::string tmp; + proto.SerializeToString(&tmp); + auto write_stream = std::make_unique(); + *write_stream << tmp; + return write_stream; +} + +absl::Status StreamingStatistic::deserializeNative(std::istream& stream) { + nighthawk::internal::StreamingStatistic proto; + std::string tmp(std::istreambuf_iterator(stream), {}); + if (!proto.ParseFromString(tmp)) { + ENVOY_LOG(error, "Failed to read back StreamingStatistic data."); + return absl::Status(absl::StatusCode::kInternal, "Failed to read back StreamingStatistic data"); + } + id_ = proto.id(); + count_ = proto.count(); + min_ = proto.min(); + max_ = proto.max(); + mean_ = proto.mean(); + accumulated_variance_ = proto.accumulated_variance(); + return absl::OkStatus(); +} + InMemoryStatistic::InMemoryStatistic() : streaming_stats_(std::make_unique()) {} void InMemoryStatistic::addValue(uint64_t sample_value) { diff --git a/source/common/statistic_impl.h b/source/common/statistic_impl.h index 0dcdab7a8..0158d3bb5 100644 --- a/source/common/statistic_impl.h +++ b/source/common/statistic_impl.h @@ -69,6 +69,8 @@ class SimpleStatistic : public StatisticImpl { StatisticPtr createNewInstanceOfSameType() const override { return std::make_unique(); }; + absl::StatusOr> serializeNative() const override; + absl::Status deserializeNative(std::istream&) override; private: double sum_x_{0}; @@ -94,6 +96,8 @@ class StreamingStatistic : public StatisticImpl { StatisticPtr createNewInstanceOfSameType() const override { return std::make_unique(); }; + absl::StatusOr> serializeNative() const override; + absl::Status deserializeNative(std::istream&) override; private: double mean_{0};