mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-03 13:02:00 +00:00
sort interactive metrics by recent update and name
This commit is contained in:
parent
0cf896f5a0
commit
79aa9ef665
@ -158,11 +158,6 @@ std::string_view setColorForTimeBasedMetricsProgress(ProfileEvents::ValueType va
|
||||
return colors[dist];
|
||||
}
|
||||
|
||||
std::string_view setColorForStaleMetrics()
|
||||
{
|
||||
return "\033[38;5;236m"; /// Dark Grey
|
||||
}
|
||||
|
||||
std::string_view setColorForDocumentation()
|
||||
{
|
||||
return "\033[38;5;236m"; /// Dark Grey
|
||||
@ -230,9 +225,10 @@ void ProgressTable::writeTable(WriteBufferFromFileDescriptor & message, bool sho
|
||||
|
||||
for (auto & [name, per_host_info] : metrics)
|
||||
{
|
||||
if (!per_host_info.isFresh(elapsed_sec))
|
||||
continue;
|
||||
|
||||
message << "\n";
|
||||
if (per_host_info.isStale(elapsed_sec))
|
||||
message << setColorForStaleMetrics();
|
||||
writeWithWidth(message, name, column_event_name_width);
|
||||
|
||||
auto value = per_host_info.getSummaryValue();
|
||||
@ -272,7 +268,7 @@ void ProgressTable::writeTable(WriteBufferFromFileDescriptor & message, bool sho
|
||||
message << CLEAR_TO_END_OF_LINE;
|
||||
}
|
||||
|
||||
message << moveUpNLines(tableSize());
|
||||
message << moveUpNLines(getFreshMetricsCount(elapsed_sec));
|
||||
message.next();
|
||||
}
|
||||
|
||||
@ -316,7 +312,25 @@ void ProgressTable::updateTable(const Block & block)
|
||||
|
||||
std::lock_guard lock{mutex};
|
||||
const auto & event_name_to_event = getEventNameToEvent();
|
||||
|
||||
std::vector<std::pair<std::string, size_t>> name_and_row_num_list;
|
||||
for (size_t row_num = 0, rows = block.rows(); row_num < rows; ++row_num)
|
||||
{
|
||||
auto thread_id = array_thread_id[row_num];
|
||||
if (thread_id != THREAD_GROUP_ID)
|
||||
continue;
|
||||
|
||||
auto name = names.getDataAt(row_num).toString();
|
||||
name_and_row_num_list.emplace_back(name, row_num);
|
||||
}
|
||||
/// Sort by metric name in reverse order, as the most recently updated entries are promoted to the front
|
||||
/// of the metric's list.
|
||||
std::sort(
|
||||
name_and_row_num_list.begin(),
|
||||
name_and_row_num_list.end(),
|
||||
[](const auto & a, const auto & b) { return a.first != b.first ? a.first > b.first : a.second < b.second; });
|
||||
|
||||
for (const auto & [name, row_num] : name_and_row_num_list)
|
||||
{
|
||||
auto thread_id = array_thread_id[row_num];
|
||||
|
||||
@ -326,8 +340,9 @@ void ProgressTable::updateTable(const Block & block)
|
||||
if (thread_id != THREAD_GROUP_ID)
|
||||
continue;
|
||||
|
||||
chassert(name == names.getDataAt(row_num).toString());
|
||||
|
||||
auto value = array_values[row_num];
|
||||
auto name = names.getDataAt(row_num).toString();
|
||||
auto host_name = host_names.getDataAt(row_num).toString();
|
||||
auto type = static_cast<ProfileEvents::Type>(array_type[row_num]);
|
||||
|
||||
@ -339,11 +354,16 @@ void ProgressTable::updateTable(const Block & block)
|
||||
if (value == 0)
|
||||
continue;
|
||||
|
||||
auto it = metrics.find(name);
|
||||
if (it == metrics.end())
|
||||
it = metrics.try_emplace(name).first;
|
||||
auto it = metrics_iterators.find(name);
|
||||
if (it == metrics_iterators.end())
|
||||
{
|
||||
metrics.emplace_front(name, MetricInfoPerHost{});
|
||||
metrics_iterators.emplace(name, metrics.begin());
|
||||
}
|
||||
else
|
||||
metrics.splice(metrics.begin(), metrics, it->second);
|
||||
|
||||
it->second.updateHostValue(host_name, type, value, time_now);
|
||||
metrics.front().second.updateHostValue(host_name, type, value, time_now);
|
||||
|
||||
max_event_name_width = std::max(max_event_name_width, name.size());
|
||||
}
|
||||
@ -362,12 +382,22 @@ void ProgressTable::resetTable()
|
||||
std::lock_guard lock{mutex};
|
||||
watch.restart();
|
||||
metrics.clear();
|
||||
metrics_iterators.clear();
|
||||
}
|
||||
|
||||
size_t ProgressTable::tableSize() const
|
||||
size_t ProgressTable::getFreshMetricsCount(double time_now) const
|
||||
{
|
||||
auto count = std::count_if(
|
||||
metrics.cbegin(),
|
||||
metrics.cend(),
|
||||
[&time_now](const auto & elem)
|
||||
{
|
||||
const auto & per_host_info = elem.second;
|
||||
return per_host_info.isFresh(time_now);
|
||||
});
|
||||
|
||||
/// Number of lines + header.
|
||||
return metrics.empty() ? 0 : metrics.size() + 1;
|
||||
return count == 0 ? 0 : count + 1;
|
||||
}
|
||||
|
||||
size_t ProgressTable::getColumnDocumentationWidth(size_t terminal_width) const
|
||||
@ -409,9 +439,11 @@ void ProgressTable::MetricInfo::updateValue(Int64 new_value, double new_time)
|
||||
update_time = new_time;
|
||||
}
|
||||
|
||||
bool ProgressTable::MetricInfo::isStale(double now) const
|
||||
bool ProgressTable::MetricInfo::isFresh(double now) const
|
||||
{
|
||||
return update_time != 0 && now - update_time >= 5.0;
|
||||
constexpr double freshness_threshold = 3.0;
|
||||
chassert(now >= update_time);
|
||||
return update_time != 0 && now - update_time <= freshness_threshold;
|
||||
}
|
||||
|
||||
double ProgressTable::MetricInfo::calculateProgress(double time_now) const
|
||||
@ -469,8 +501,8 @@ double ProgressTable::MetricInfoPerHost::getMaxProgress() const
|
||||
return max_progress;
|
||||
}
|
||||
|
||||
bool ProgressTable::MetricInfoPerHost::isStale(double now) const
|
||||
bool ProgressTable::MetricInfoPerHost::isFresh(double now) const
|
||||
{
|
||||
return std::all_of(host_to_metric.cbegin(), host_to_metric.cend(), [&now](const auto & p) { return p.second.isStale(now); });
|
||||
return std::any_of(host_to_metric.cbegin(), host_to_metric.cend(), [&now](const auto & p) { return p.second.isFresh(now); });
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <Common/ProfileEvents.h>
|
||||
#include <Common/Stopwatch.h>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
@ -47,7 +48,7 @@ private:
|
||||
void updateValue(Int64 new_value, double new_time);
|
||||
double calculateProgress(double time_now) const;
|
||||
double getValue() const;
|
||||
bool isStale(double now) const;
|
||||
bool isFresh(double now) const;
|
||||
|
||||
private:
|
||||
const ProfileEvents::Type type;
|
||||
@ -79,7 +80,7 @@ private:
|
||||
double getSummaryValue();
|
||||
double getSummaryProgress(double time_now);
|
||||
double getMaxProgress() const;
|
||||
bool isStale(double now) const;
|
||||
bool isFresh(double now) const;
|
||||
|
||||
private:
|
||||
std::unordered_map<HostName, MetricInfo> host_to_metric;
|
||||
@ -87,13 +88,17 @@ private:
|
||||
};
|
||||
|
||||
size_t tableSize() const;
|
||||
size_t getFreshMetricsCount(double time_now) const;
|
||||
|
||||
size_t getColumnDocumentationWidth(size_t terminal_width) const;
|
||||
|
||||
using MetricName = String;
|
||||
using Metric = std::pair<MetricName, MetricInfoPerHost>;
|
||||
|
||||
/// The server periodically sends Block with profile events.
|
||||
/// This information is stored here.
|
||||
std::map<MetricName, MetricInfoPerHost> metrics;
|
||||
std::list<Metric> metrics;
|
||||
std::map<MetricName, std::list<Metric>::iterator> metrics_iterators;
|
||||
|
||||
/// It is possible concurrent access to the metrics.
|
||||
std::mutex mutex;
|
||||
|
Loading…
Reference in New Issue
Block a user