From 2ff006da4aed659a73e45c790c75790bdeb70f08 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 15 Jan 2015 14:35:01 +0200 Subject: [PATCH] core: calculate system load and report it via collectd --- core/reactor.cc | 41 ++++++++++++++++++++++++++++++++++++++++- core/reactor.hh | 2 ++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/core/reactor.cc b/core/reactor.cc index 3ede6f875d..e0716a9fa1 100644 --- a/core/reactor.cc +++ b/core/reactor.cc @@ -613,6 +613,12 @@ reactor::register_collectd_metrics() { , scollectd::make_typed(scollectd::data_type::GAUGE , std::bind(&decltype(_timers)::size, &_timers)) ), + scollectd::add_polled_metric(scollectd::type_instance_id("reactor" + , scollectd::per_cpu_plugin_instance + , "queue_length", "idle") + , scollectd::make_typed(scollectd::data_type::GAUGE, + [this] () -> uint32_t { return _load * 100; }) + ), scollectd::add_polled_metric( scollectd::type_instance_id("memory", scollectd::per_cpu_plugin_instance, @@ -729,9 +735,31 @@ int reactor::run() { return false; }); + using namespace std::chrono_literals; + timer load_timer; + std::chrono::high_resolution_clock::rep idle_count = 0; + auto idle_start = std::chrono::high_resolution_clock::now(), idle_end = idle_start; + load_timer.set_callback([this, &idle_count, &idle_start, &idle_end] () mutable { + auto load = double(idle_count + (idle_end - idle_start).count()) / double(std::chrono::duration_cast(1s).count()); + load = std::min(load, 1.0); + idle_count = 0; + idle_start = idle_end; + _loads.push_front(load); + if (_loads.size() > 5) { + auto drop = _loads.back(); + _loads.pop_back(); + _load -= (drop/5); + } + _load += (load/5); + }); + load_timer.arm_periodic(1s); + + bool idle = false; + while (true) { run_tasks(_pending_tasks, _task_quota); if (_stopped) { + load_timer.cancel(); run_tasks(_at_destroy_tasks, _at_destroy_tasks.size()); if (_id == 0) { smp::join_all(); @@ -739,7 +767,18 @@ int reactor::run() { break; } - poll_once(); + if (!poll_once() && _pending_tasks.empty()) { + idle_end = std::chrono::high_resolution_clock::now(); + if (!idle) { + idle_start = idle_end; + idle = true; + } + } else { + if (idle) { + idle_count += (idle_end - idle_start).count(); + idle = false; + } + } } return _return; } diff --git a/core/reactor.hh b/core/reactor.hh index bb81bff53b..40874c8928 100644 --- a/core/reactor.hh +++ b/core/reactor.hh @@ -626,6 +626,8 @@ private: promise<> _timer_promise; std::experimental::optional _epoll_poller; const bool _reuseport; + circular_buffer _loads; + double _load = 0; private: void abort_on_error(int ret); template