Skip to content

Commit

Permalink
clean label
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos committed Aug 12, 2024
1 parent 3af0f87 commit a2d0961
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 1 deletion.
21 changes: 21 additions & 0 deletions include/ylt/metric/counter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ class basic_dynamic_counter : public dynamic_metric {
labels_value, thread_local_value<value_type>(dupli_count_));
if (r) {
g_user_metric_label_count.local_value()++;
if (ylt_label_max_age.count()) {
it->second.set_created_time(std::chrono::system_clock::now());
}
}
set_value(it->second.local_value(), value, op_type_t::INC);
}
Expand All @@ -232,6 +235,9 @@ class basic_dynamic_counter : public dynamic_metric {
labels_value, thread_local_value<value_type>(dupli_count_));
if (r) {
g_user_metric_label_count.local_value()++;
if (ylt_label_max_age.count()) {
it->second.set_created_time(std::chrono::system_clock::now());
}
}
return it->second.update(value);
}
Expand Down Expand Up @@ -271,6 +277,21 @@ class basic_dynamic_counter : public dynamic_metric {
return value_map_.size();
}

void clean_expired_label() override {
if (ylt_label_max_age.count() == 0) {
return;
}

auto now = std::chrono::system_clock::now();
std::lock_guard lock(mtx_);
std::erase_if(value_map_, [&now](auto &pair) {
bool r = std::chrono::duration_cast<std::chrono::seconds>(
now - pair.second.get_created_time())
.count() >= ylt_label_max_age.count();
return r;
});
}

void remove_label_value(
const std::map<std::string, std::string> &labels) override {
{
Expand Down
3 changes: 3 additions & 0 deletions include/ylt/metric/gauge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class basic_dynamic_gauge : public basic_dynamic_counter<value_type, N> {
labels_value, thread_local_value<value_type>(dupli_count_));
if (r) {
g_user_metric_label_count.local_value()++;
if (ylt_label_max_age.count()) {
it->second.set_created_time(std::chrono::system_clock::now());
}
}

set_value(it->second.local_value(), value, op_type_t::DEC);
Expand Down
12 changes: 12 additions & 0 deletions include/ylt/metric/metric.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class metric_t {
labels_value_.end();
}

virtual void clean_expired_label() {}

virtual bool has_label_value(const std::vector<std::string>& label_value) {
return labels_value_ == label_value;
}
Expand Down Expand Up @@ -229,11 +231,21 @@ inline std::atomic<int64_t> g_user_metric_count = 0;
inline std::atomic<int64_t> ylt_metric_capacity = 10000000;
inline int64_t ylt_label_capacity = 20000000;

inline std::chrono::seconds ylt_label_max_age{0};
inline std::chrono::seconds ylt_label_check_expire_duration{0};

inline void set_metric_capacity(int64_t max_count) {
ylt_metric_capacity = max_count;
}

inline void set_label_capacity(int64_t max_label_count) {
ylt_label_capacity = max_label_count;
}

inline void set_label_max_age(
std::chrono::seconds max_age,
std::chrono::seconds check_duration = std::chrono::seconds(60 * 10)) {
ylt_label_max_age = max_age;
ylt_label_check_expire_duration = check_duration;
}
} // namespace ylt::metric
31 changes: 30 additions & 1 deletion include/ylt/metric/metric_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,34 @@ class dynamic_metric_manager {
}

private:
dynamic_metric_manager() = default;
void clean_label_expired() {
executor_ = coro_io::create_io_context_pool(1);
timer_ = std::make_shared<coro_io::period_timer>(executor_->get_executor());
check_label_expired().via(executor_->get_executor()).start([](auto&&) {
});
}

async_simple::coro::Lazy<void> check_label_expired() {
auto timer = timer_;
timer_->expires_after(ylt_label_check_expire_duration);
bool r = co_await timer_->async_await();
if (!r) {
co_return;
}

std::unique_lock lock(mtx_);
for (auto& [_, m] : metric_map_) {
m->clean_expired_label();
}
lock.unlock();
co_await check_label_expired();
}

dynamic_metric_manager() {
if (ylt_label_max_age.count() > 0) {
clean_label_expired();
}
}

std::vector<std::shared_ptr<dynamic_metric>> get_metric_by_label_value(
const std::vector<std::string>& label_value) {
Expand All @@ -532,6 +559,8 @@ class dynamic_metric_manager {

std::shared_mutex mtx_;
std::unordered_map<std::string, std::shared_ptr<dynamic_metric>> metric_map_;
std::shared_ptr<coro_io::period_timer> timer_ = nullptr;
std::shared_ptr<coro_io::io_context_pool> executor_ = nullptr;
};

struct ylt_default_metric_tag_t {};
Expand Down
8 changes: 8 additions & 0 deletions include/ylt/metric/thread_local_value.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include <atomic>
#include <chrono>
#include <cstddef>
#include <thread>
#include <vector>
Expand Down Expand Up @@ -98,7 +99,14 @@ class thread_local_value {
return val;
}

void set_created_time(std::chrono::system_clock::time_point tm) {
created_time_ = tm;
}

auto get_created_time() { return created_time_; }

private:
std::vector<std::atomic<std::atomic<value_type> *>> duplicates_;
std::chrono::system_clock::time_point created_time_{};
};
} // namespace ylt::metric
16 changes: 16 additions & 0 deletions src/metric/tests/test_metric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ using namespace ylt;
using namespace ylt::metric;

struct metrc_tag {};

struct test_tag {};

TEST_CASE("test metric manager clean expired label") {
set_label_max_age(std::chrono::seconds(1), std::chrono::seconds(1));
auto& inst = dynamic_metric_manager<test_tag>::instance();
auto [ec, c] = inst.create_metric_dynamic<dynamic_counter_1t>(
std::string("some_counter"), "", std::array<std::string, 1>{"url"});
c->inc({"/"});
c->inc({"/test"});
std::this_thread::sleep_for(std::chrono::seconds(2));
c->inc({"/index"});
size_t count = c->label_value_count();
CHECK(count == 1);
}

TEST_CASE("test metric manager") {
auto c = std::make_shared<counter_t>("test1", "");
auto g = std::make_shared<gauge_t>("test2", "");
Expand Down

0 comments on commit a2d0961

Please sign in to comment.