Skip to content

Commit

Permalink
[metric]Fix summary (#736)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Aug 6, 2024
1 parent 2086dd4 commit fecc43a
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 8 deletions.
15 changes: 13 additions & 2 deletions include/ylt/metric/counter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,13 @@ class basic_counter : public metric_t {
virtual ~basic_counter() { g_user_metric_count--; }

value_type value() {
if (!labels_value_.empty()) {
value_type val = atomic_value_map_[labels_value_].value();
return val;
}

if (!labels_name_.empty()) {
throw std::invalid_argument("it's not a default value counter!");
throw std::invalid_argument("it's not a dynamic counter!");
}
return default_label_value_.value();
}
Expand Down Expand Up @@ -168,8 +173,14 @@ class basic_counter : public metric_t {
#endif

void inc(value_type val = 1) {
if (!labels_value_.empty()) {
set_value<true>(atomic_value_map_[labels_value_].local_value(), val,
op_type_t::INC);
return;
}

if (!labels_name_.empty()) {
throw std::invalid_argument("it's not a default value counter!");
throw std::invalid_argument("it's not a dynamic counter!");
}

if (val < 0) {
Expand Down
8 changes: 7 additions & 1 deletion include/ylt/metric/gauge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ class basic_gauge : public basic_counter<value_type> {
}

void dec(value_type value = 1) {
if (!labels_value_.empty()) {
set_value_static(atomic_value_map_[labels_value_].local_value(), value,
op_type_t::DEC);
return;
}

if (!labels_name_.empty()) {
throw std::bad_function_call();
throw std::invalid_argument("it's not a dynamic counter!");
}
#ifdef __APPLE__
if constexpr (std::is_floating_point_v<value_type>) {
Expand Down
5 changes: 5 additions & 0 deletions include/ylt/metric/histogram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ class basic_histogram : public metric_t {
}

void observe(value_type value) {
if (!labels_value_.empty()) {
observe(labels_value_, value);
return;
}

if (!use_atomic_ || !labels_name_.empty()) {
throw std::invalid_argument("not a default label metric");
}
Expand Down
28 changes: 23 additions & 5 deletions include/ylt/metric/summary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ class summary_t : public metric_t {
metric_t(MetricType::Summary, std::move(name), std::move(help)),
max_age_(max_age),
age_buckets_(age_buckets) {
init_block(block_);
block_->quantile_values_ =
std::make_shared<TimeWindowQuantiles>(quantiles_, max_age, age_buckets);
use_atomic_ = true;
g_user_metric_count++;
init_no_label(max_age, age_buckets);
}

summary_t(std::string name, std::string help, Quantiles quantiles,
Expand All @@ -71,6 +67,11 @@ class summary_t : public metric_t {
std::move(static_labels)),
max_age_(max_age),
age_buckets_(age_buckets) {
if (static_labels_.empty()) {
init_no_label(max_age, age_buckets);
return;
}

init_block(labels_block_);
labels_block_->label_quantile_values_[labels_value_] =
std::make_shared<TimeWindowQuantiles>(quantiles_, max_age, age_buckets);
Expand Down Expand Up @@ -108,6 +109,11 @@ class summary_t : public metric_t {
};

void observe(double value) {
if (!labels_value_.empty()) {
observe(labels_value_, value);
return;
}

if (!labels_name_.empty()) {
throw std::invalid_argument("not a default label metric");
}
Expand Down Expand Up @@ -148,6 +154,10 @@ class summary_t : public metric_t {

async_simple::coro::Lazy<std::vector<double>> get_rates(double &sum,
uint64_t &count) {
if (!labels_value_.empty()) {
co_return co_await get_rates(labels_value_, sum, count);
}

std::vector<double> vec;
if (quantiles_.empty()) {
co_return std::vector<double>{};
Expand Down Expand Up @@ -303,6 +313,14 @@ class summary_t : public metric_t {
});
}

void init_no_label(std::chrono::milliseconds max_age, int age_buckets) {
init_block(block_);
block_->quantile_values_ =
std::make_shared<TimeWindowQuantiles>(quantiles_, max_age, age_buckets);
use_atomic_ = true;
g_user_metric_count++;
}

async_simple::coro::Lazy<void> start(std::shared_ptr<block_t> block) {
double sample;
size_t count = 1000000;
Expand Down
59 changes: 59 additions & 0 deletions src/metric/tests/test_metric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ auto g_counter = my_manager::instance().create_metric_dynamic<counter_t>(
"test_g_counter", "");

TEST_CASE("test no lable") {
{
std::map<std::string, std::string> customMap = {};
auto summary = std::make_shared<summary_t>(
"test", "help",
summary_t::Quantiles{
{0.5, 0.05}, {0.9, 0.01}, {0.95, 0.005}, {0.99, 0.001}},
customMap);
summary->observe(100);
}
g_counter->inc();
CHECK(g_counter->value() == 1);
{
Expand Down Expand Up @@ -103,6 +112,22 @@ TEST_CASE("test with atomic") {
std::cout << str1;
CHECK(str.find("} 10") != std::string::npos);
CHECK(str1.find("} 1") != std::string::npos);

{
gauge_t g("get_qps", "get qps",
std::map<std::string, std::string>{{"method", "POST"},
{"url", "/test"}});
g.inc();
g.inc({"POST", "/test"});
CHECK(g.value() == 2);
CHECK(g.value({"POST", "/test"}) == 2);
g.dec();
CHECK(g.value() == 1);
CHECK(g.value({"POST", "/test"}) == 1);
g.dec({"POST", "/test"});
CHECK(g.value() == 0);
CHECK(g.value({"POST", "/test"}) == 0);
}
}

TEST_CASE("test counter with dynamic labels value") {
Expand Down Expand Up @@ -576,6 +601,20 @@ TEST_CASE("test get metric by static labels and label") {
metric_mgr::instance().get_metric_by_label_static({"method", "GET"});
CHECK(vec.size() == 4);

{
using metric_mgr2 = metric_manager_t<test_id_t<19>>;
auto s2 = metric_mgr2::instance().create_metric_static<summary_t>(
"http_req_static_summary2", "help",
summary_t::Quantiles{
{0.5, 0.05}, {0.9, 0.01}, {0.95, 0.005}, {0.99, 0.001}},
std::map<std::string, std::string>{{"method", "GET"}, {"url", "/"}});
s2->observe(23);

auto vec =
metric_mgr2::instance().get_metric_by_label_static({"method", "GET"});
CHECK(vec.size() == 1);
}

vec = metric_mgr::instance().get_metric_by_label_static({"url", "/"});
CHECK(vec.size() == 4);

Expand Down Expand Up @@ -714,6 +753,23 @@ TEST_CASE("test histogram serialize with dynamic labels") {
#endif
}

TEST_CASE("test histogram serialize with static labels default") {
histogram_t h(
"test", "help", {5.23, 10.54, 20.0, 50.0, 100.0},
std::map<std::string, std::string>{{"method", "GET"}, {"url", "/"}});
h.observe(23);
auto counts = h.get_bucket_counts();
CHECK(counts[3]->value({"GET", "/"}) == 1);
h.observe(42);
CHECK(counts[3]->value({"GET", "/"}) == 2);
h.observe({"GET", "/"}, 60);
CHECK(counts[4]->value({"GET", "/"}) == 1);
h.observe({"GET", "/"}, 120);
CHECK(counts[5]->value({"GET", "/"}) == 1);
h.observe(1);
CHECK(counts[0]->value({"GET", "/"}) == 1);
}

TEST_CASE("test histogram serialize with static labels") {
histogram_t h(
"test", "help", {5.23, 10.54, 20.0, 50.0, 100.0},
Expand Down Expand Up @@ -796,6 +852,9 @@ TEST_CASE("test summary with static labels") {
summary.get_rates({"GET", "/"}, sum, count));
std::cout << rates.size() << "\n";

auto rates1 = async_simple::coro::syncAwait(summary.get_rates(sum, count));
CHECK(rates == rates1);

std::string str;
async_simple::coro::syncAwait(summary.serialize_async(str));
std::cout << str;
Expand Down

0 comments on commit fecc43a

Please sign in to comment.