use futures::executor::block_on;
use libp2prs_swarm::Control;
use prometheus::core::{Collector, Desc};
use prometheus::Counter;
use prometheus::{proto, CounterVec, Opts};
use std::collections::HashMap;
pub(crate) struct Exporter {
control: Control,
desc: Desc,
}
impl Collector for Exporter {
fn desc(&self) -> Vec<&Desc> {
vec![&self.desc]
}
fn collect(&self) -> Vec<proto::MetricFamily> {
let mut family = Vec::<proto::MetricFamily>::new();
let recv_count = Counter::new("recv_pkg_counts", "Total number of packages received").unwrap();
let recv_size = Counter::new("recv_pkg_bytes", "Total bytes of packages received").unwrap();
let (count, size) = self.control.get_recv_count_and_size();
recv_count.inc_by(count as f64);
recv_size.inc_by(size as f64);
family.push(recv_count.collect()[0].clone());
family.push(recv_size.collect()[0].clone());
let sent_count = Counter::new("sent_pkg_counts", "Total number of packages sent").unwrap();
let sent_size = Counter::new("sent_pkg_bytes", "Total size of packages sent").unwrap();
let (count, size) = self.control.get_sent_count_and_size();
sent_count.inc_by(count as f64);
sent_size.inc_by(size as f64);
family.push(sent_count.collect()[0].clone());
family.push(sent_size.collect()[0].clone());
let mut state = self.control.clone();
block_on(async {
let info = state.retrieve_networkinfo().await.unwrap();
let connect_peer = Counter::new("peer_count", "Current number of connection peers").unwrap();
connect_peer.inc_by(info.num_peers as f64);
family.push(connect_peer.collect()[0].clone());
let connection_count = Counter::new("connection_count", "Current number of connections").unwrap();
connection_count.inc_by(info.num_connections as f64);
family.push(connection_count.collect()[0].clone());
let connection_pending = Counter::new("connection_pending", "Current num of pending connections").unwrap();
connection_pending.inc_by(info.num_connections_pending as f64);
family.push(connection_pending.collect()[0].clone());
let connection_established = Counter::new("connection_established", "Current num of established connections").unwrap();
connection_established.inc_by(info.num_connections_established as f64);
family.push(connection_established.collect()[0].clone());
let active_stream = Counter::new("active_stream", "Current num of active streams").unwrap();
active_stream.inc_by(info.num_active_streams as f64);
family.push(active_stream.collect()[0].clone());
});
let opt = Opts::new("peer_id_input_bytes", "Each peer input bytes");
let peer = CounterVec::new(opt, &["peer_id"]).unwrap();
for (k, v) in self.control.peer_in_iter() {
let mut map = HashMap::new();
let value = k.to_string();
map.insert("peer_id", value.as_str());
peer.with(&map).inc_by(v as f64);
}
family.push(peer.collect()[0].clone());
let opt = Opts::new("peer_id_output_bytes", "Each peer output bytes");
let peer = CounterVec::new(opt, &["peer_id"]).unwrap();
for (k, v) in self.control.peer_out_iter() {
let mut map = HashMap::new();
let value = k.to_string();
map.insert("peer_id", value.as_str());
peer.with(&map).inc_by(v as f64);
}
family.push(peer.collect()[0].clone());
let opt = Opts::new("protocol_input_bytes", "Each protocol input bytes");
let protocol = CounterVec::new(opt, &["protocol"]).unwrap();
for (k, v) in self.control.protocol_in_iter() {
let mut map = HashMap::new();
let value = k.to_string();
map.insert("protocol", value.as_str());
protocol.with(&map).inc_by(v as f64);
}
family.push(protocol.collect()[0].clone());
let opt = Opts::new("protocol_output_bytes", "Each protocol output bytes");
let protocol = CounterVec::new(opt, &["protocol"]).unwrap();
for (k, v) in self.control.protocol_out_iter() {
let mut map = HashMap::new();
let value = k.to_string();
map.insert("protocol", value.as_str());
protocol.with(&map).inc_by(v as f64);
}
family.push(protocol.collect()[0].clone());
family
}
}
impl Exporter {
pub fn new(control: Control) -> Self {
let d = Desc::new(
"libp2prs_exporter".into(),
"An Exporter that exposes metrics in libp2p_rs".into(),
vec![],
HashMap::new(),
);
Exporter { control, desc: d.unwrap() }
}
}