diff --git a/include/ylt/metric/summary.hpp b/include/ylt/metric/summary.hpp index 5a565a8ed..c2f84f8a7 100644 --- a/include/ylt/metric/summary.hpp +++ b/include/ylt/metric/summary.hpp @@ -58,7 +58,10 @@ class summary_t : public static_metric { std::sort(quantiles_.begin(), quantiles_.end()); } - void observe(float value) { impl_.insert(value); } + void observe(float value) { + has_refreshed_.store(true, std::memory_order_relaxed); + impl_.insert(value); + } std::vector get_rates() { uint64_t count; @@ -85,7 +88,7 @@ class summary_t : public static_metric { double sum = 0; uint64_t count = 0; auto rates = get_rates(sum, count); - if (count == 0) { + if (count == 0 && !has_refreshed_.load(std::memory_order_relaxed)) { return; } serialize_head(str); @@ -121,7 +124,7 @@ class summary_t : public static_metric { json_summary_metric_t metric; metric.quantiles_value = get_rates(metric.sum, metric.count); - if (metric.count == 0) { + if (metric.count == 0 && !has_refreshed_.load(std::memory_order_relaxed)) { return; } metric.labels.reserve(labels_value_.size()); @@ -132,6 +135,7 @@ class summary_t : public static_metric { #endif private: + std::atomic has_refreshed_; std::vector quantiles_; ylt::metric::detail::summary_impl impl_; }; diff --git a/src/metric/tests/test_metric.cpp b/src/metric/tests/test_metric.cpp index f9d0e74fd..2e4966665 100644 --- a/src/metric/tests/test_metric.cpp +++ b/src/metric/tests/test_metric.cpp @@ -978,9 +978,24 @@ TEST_CASE("test summary refresh") { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> distr(1, 100); + std::string str; + summary.serialize_to_json(str); + CHECK(str.size() == 0); + str = ""; + summary.serialize(str); + CHECK(str.size() == 0); + + std::this_thread::sleep_for(1001ms); + summary.serialize_to_json(str); + CHECK(str.size() == 0); + str = ""; + summary.serialize(str); + CHECK(str.size() == 0); + for (int i = 0; i < 50; i++) { summary.observe(i); } + double sum; uint64_t cnt; summary.get_rates(sum, cnt); @@ -1002,7 +1017,11 @@ TEST_CASE("test summary refresh") { CHECK(cnt == 10); std::this_thread::sleep_for(500ms); summary.get_rates(sum, cnt); - CHECK(cnt == 0); + summary.serialize_to_json(str); + CHECK(str.size() > 0); + str = ""; + summary.serialize(str); + CHECK(str.size() > 0); } TEST_CASE("test register metric") {