Skip to content

Commit

Permalink
[metric]simplify clean (qicosmos#603)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Jun 18, 2024
1 parent 1e180fb commit 235d3ed
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 133 deletions.
20 changes: 5 additions & 15 deletions include/cinatra/ylt/metric/counter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,8 @@ class counter_t : public metric_t {
}
}

std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
value_map() override {
std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
map;
metric_hash_map<double> value_map() override {
metric_hash_map<double> map;
if (use_atomic_) {
map = {atomic_value_map_.begin(), atomic_value_map_.end()};
}
Expand Down Expand Up @@ -192,9 +188,7 @@ class counter_t : public metric_t {
}
}

std::map<std::vector<std::string>, std::atomic<double>,
std::less<std::vector<std::string>>>
&atomic_value_map() {
metric_hash_map<std::atomic<double>> &atomic_value_map() {
return atomic_value_map_;
}

Expand Down Expand Up @@ -298,14 +292,10 @@ class counter_t : public metric_t {
}
}

std::map<std::vector<std::string>, std::atomic<double>,
std::less<std::vector<std::string>>>
atomic_value_map_;
metric_hash_map<std::atomic<double>> atomic_value_map_;
std::atomic<double> default_lable_value_ = 0;

std::mutex mtx_;
std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
value_map_;
metric_hash_map<double> value_map_;
};
} // namespace ylt::metric
6 changes: 1 addition & 5 deletions include/cinatra/ylt/metric/histogram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,7 @@ class histogram_t : public metric_t {

auto get_bucket_counts() { return bucket_counts_; }

std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
value_map() override {
return sum_->value_map();
}
metric_hash_map<double> value_map() override { return sum_->value_map(); }

void serialize(std::string &str) override {
if (!sum_->labels_name().empty()) {
Expand Down
84 changes: 20 additions & 64 deletions include/cinatra/ylt/metric/metric.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,25 @@ struct metric_filter_options {
bool is_white = true;
};

struct vector_hash {
size_t operator()(const std::vector<std::string>& vec) const {
unsigned int seed = 131;
unsigned int hash = 0;

for (const auto& str : vec) {
for (auto ch : str) {
hash = hash * seed + ch;
}
}

return (hash & 0x7FFFFFFF);
}
};

template <typename T>
using metric_hash_map =
std::unordered_map<std::vector<std::string>, T, vector_hash>;

class metric_t {
public:
metric_t() = default;
Expand Down Expand Up @@ -102,11 +121,7 @@ class metric_t {
return static_labels_;
}

virtual std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
value_map() {
return {};
}
virtual metric_hash_map<double> value_map() { return {}; }

virtual void serialize(std::string& str) {}

Expand Down Expand Up @@ -248,14 +263,6 @@ struct metric_manager_t {
return r;
}

static void set_metric_max_age(std::chrono::steady_clock::duration max_age,
std::chrono::steady_clock::duration
check_duration = std::chrono::minutes(5)) {
metric_max_age_ = max_age;
metric_check_duration_ = check_duration;
start_check();
}

static auto metric_map_static() { return metric_map_impl<false>(); }
static auto metric_map_dynamic() { return metric_map_impl<true>(); }

Expand Down Expand Up @@ -565,63 +572,12 @@ struct metric_manager_t {
return filtered_metrics;
}

static void check_impl() {
check_timer_->expires_after(metric_check_duration_);
check_timer_->async_wait([](std::error_code ec) {
if (ec) {
return;
}

check_clean_metrics();
check_impl();
});
}

static void start_check() {
if (has_start_check_metric_) {
return;
}

has_start_check_metric_ = true;

executor_ = coro_io::create_io_context_pool(1);

check_timer_ =
std::make_shared<coro_io::period_timer>(executor_->get_executor());

check_impl();
}

static void check_clean_metrics() {
auto cur_time = std::chrono::system_clock::now();
{
auto lock = get_lock<true>();
for (auto it = metric_map_.begin(); it != metric_map_.end();) {
if (cur_time - it->second->get_created_time() > metric_max_age_) {
metric_map_.erase(it++);
}
else {
++it;
}
}
}
}

static inline bool has_start_check_metric_ = false;
static inline std::shared_ptr<coro_io::period_timer> check_timer_ = nullptr;
static inline std::shared_ptr<coro_io::io_context_pool> executor_ = nullptr;

static inline std::mutex mtx_;
static inline std::map<std::string, std::shared_ptr<metric_t>> metric_map_;

static inline null_mutex_t null_mtx_;
static inline std::atomic_bool need_lock_ = true;
static inline std::once_flag flag_;

static inline std::chrono::steady_clock::duration metric_max_age_{
std::chrono::hours(24)};
static inline std::chrono::steady_clock::duration metric_check_duration_{
std::chrono::minutes(5)};
};

using default_metric_manager = metric_manager_t<0>;
Expand Down
26 changes: 10 additions & 16 deletions include/cinatra/ylt/metric/summary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,24 +98,19 @@ class summary_t : public metric_t {
struct labels_block_t {
std::atomic<bool> stop_ = false;
moodycamel::ConcurrentQueue<summary_label_sample> sample_queue_;

std::map<std::vector<std::string>, std::shared_ptr<TimeWindowQuantiles>,
std::less<std::vector<std::string>>>
metric_hash_map<std::shared_ptr<TimeWindowQuantiles>>
label_quantile_values_;
std::map<std::vector<std::string>, std::uint64_t,
std::less<std::vector<std::string>>>
label_count_;
std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
label_sum_;
metric_hash_map<uint64_t> label_count_;
metric_hash_map<double> label_sum_;
};

void observe(double value) {
if (!labels_name_.empty()) {
throw std::invalid_argument("not a default label metric");
}
while (block_->sample_queue_.size_approx() >= 20000000) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
if (block_->sample_queue_.size_approx() >= 20000000) {
// TODO: record failed count.
return;
}
block_->sample_queue_.enqueue(value);

Expand All @@ -135,8 +130,9 @@ class summary_t : public metric_t {
throw std::invalid_argument("not equal with static label");
}
}
while (labels_block_->sample_queue_.size_approx() >= 20000000) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
if (labels_block_->sample_queue_.size_approx() >= 20000000) {
// TODO: record failed count.
return;
}
labels_block_->sample_queue_.enqueue({std::move(labels_value), value});

Expand Down Expand Up @@ -198,9 +194,7 @@ class summary_t : public metric_t {
co_return vec;
}

std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
value_map() override {
metric_hash_map<double> value_map() override {
auto ret = async_simple::coro::syncAwait(coro_io::post(
[this] {
return labels_block_->label_sum_;
Expand Down
10 changes: 1 addition & 9 deletions lang/how_to_use_metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ void inc(const std::vector<std::string> &labels_value, double value = 1);
void serialize(std::string &str);

// 返回带标签的指标内部的计数map,map的key是标签的值,值是对应计数,如:{{{"GET", "/"}, 100}, {{"POST", "/test"}, 20}}
std::map<std::vector<std::string>, double,
std::less<std::vector<std::string>>>
std::unordered_map<std::vector<std::string>, double, vector_hash>
value_map();
```
Expand Down Expand Up @@ -234,13 +233,6 @@ struct metric_manager_t {
static bool register_metric_static(std::shared_ptr<metric_t> metric);
static bool register_metric_dynamic(std::shared_ptr<metric_t> metric);
// 启用metric 定时清理功能,在使用metric之前设置
// max_age:设置metric的过期时间,过期之后metric会被清理
// check_duration:设置定期监测metric过期的时间间隔
static void set_metric_max_age(std::chrono::steady_clock::duration max_age,
std::chrono::steady_clock::duration
check_duration = std::chrono::minutes(5));
// 根据metric名称删除metric
static bool remove_metric_static(const std::string& name);
static bool remove_metric_dynamic(const std::string& name);
Expand Down
24 changes: 0 additions & 24 deletions tests/test_metric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,30 +777,6 @@ TEST_CASE("test summary with static labels") {
#endif
}

TEST_CASE("check clean metrics") {
using metric_mgr = metric_manager_t<11>;
metric_mgr::create_metric_dynamic<counter_t>("test_counter", "");
metric_mgr::create_metric_dynamic<counter_t>("test_counter2", "");
metric_mgr::create_metric_dynamic<histogram_t>(
"http_req_static_hist", "help",
std::vector<double>{5.23, 10.54, 20.0, 50.0, 100.0},
std::vector<std::string>{"method", "url"});

metric_mgr::create_metric_dynamic<summary_t>(
"http_req_static_summary", "help",
summary_t::Quantiles{
{0.5, 0.05}, {0.9, 0.01}, {0.95, 0.005}, {0.99, 0.001}},
std::vector<std::string>{"method", "url"});

CHECK(metric_mgr::metric_count_dynamic() == 4);
metric_mgr::set_metric_max_age(std::chrono::milliseconds(10),
std::chrono::milliseconds(10));

std::this_thread::sleep_for(std::chrono::milliseconds(100));

CHECK(metric_mgr::metric_count_dynamic() == 0);
}

DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007)
int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }
DOCTEST_MSVC_SUPPRESS_WARNING_POP

0 comments on commit 235d3ed

Please sign in to comment.