metrics: implement metrics renderer into iosample bar

Summary: This allow to render metrics in the real time, similar to how we render network usage

Reviewed By: DurhamG

Differential Revision: D30137295

fbshipit-source-id: 8843b574971c1ccaaae0727be6f9d46d1d90625f
This commit is contained in:
Andrey Chursin 2021-08-10 14:08:24 -07:00 committed by Facebook GitHub Bot
parent 89fb80e0da
commit 46b99410db
2 changed files with 32 additions and 8 deletions

View File

@ -5,5 +5,7 @@ version = "0.1.0"
edition = "2018"
[dependencies]
async-runtime = { path = "../../async-runtime" }
metrics = { path = ".." }
progress-model = { path = "../../progress/model" }
tracing = "0.1"

View File

@ -6,6 +6,9 @@
*/
use metrics::{Counter, Registry};
use progress_model::Registry as ProgressRegistry;
use progress_model::{IoSample, IoTimeSeries};
use std::collections::HashSet;
use std::env;
use std::sync::Weak;
use std::thread;
@ -35,11 +38,11 @@ fn init(config: &str, guard: Weak<()>) {
.unwrap();
}
fn worker(config: Vec<(MetricsFilter, Renderer)>, guard: Weak<()>) {
fn worker(mut config: Vec<(MetricsFilter, Renderer)>, guard: Weak<()>) {
let registry = Registry::global();
while guard.upgrade().is_some() {
let metrics = registry.counters();
for (filter, renderer) in &config {
for (filter, renderer) in &mut config {
let filtered = metrics.iter().filter_map(|(name, v)| {
if filter.matches(name) {
Some((*name, *v))
@ -64,7 +67,7 @@ fn parse_config(config: &str) -> Vec<(MetricsFilter, Renderer)> {
if split.next().is_some() {
error!("Progress render does not have parameters, extra parameters ignored");
}
Renderer::ProgressBar
Renderer::ProgressBar(Default::default())
}
Some(other) => {
error!("Invalid metrics renderer: {}", other);
@ -101,17 +104,36 @@ impl MetricsFilter {
}
enum Renderer {
ProgressBar,
ProgressBar(HashSet<&'static str>),
}
impl Renderer {
pub fn render(&self, metrics: Vec<(&'static str, &'static Counter)>) {
pub fn render(&mut self, metrics: Vec<(&'static str, &'static Counter)>) {
match self {
Self::ProgressBar => self.render_progress(metrics),
Self::ProgressBar(inner) => Self::render_progress(inner, metrics),
}
}
fn render_progress(&self, _metrics: Vec<(&'static str, &'static Counter)>) {
unimplemented!()
fn render_progress(
inner: &mut HashSet<&'static str>,
metrics: Vec<(&'static str, &'static Counter)>,
) {
let progress_registry = ProgressRegistry::main();
for (name, counter) in metrics {
if !inner.insert(name) {
continue;
}
let take_sample = move || {
// This abuses API little bit by supplying random counter into IoSample, need to fix later
IoSample::from_io_bytes(counter.value() as _, 0)
};
let visible_name = format!("{:.<32}", name);
let time_series = IoTimeSeries::new(visible_name, "");
let task =
time_series.async_sampling(take_sample, IoTimeSeries::default_sample_interval());
async_runtime::spawn(task);
progress_registry.register_io_time_series(&time_series);
}
}
}