Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(metrics): Upgrade to prometheus-client v0.19.0 #3207

Merged
merged 10 commits into from Jan 3, 2023
5 changes: 4 additions & 1 deletion misc/metrics/CHANGELOG.md
@@ -1,11 +1,13 @@
# 0.12.0 [unreleased]

- Update to `libp2p-core` `v0.39.0`.
- Update to `prometheus-client` `v0.19.0`. See [PR 3207].

- Add `connections_establishment_duration` metric. See [PR 3134].

- Bump MSRV to 1.65.0.

- Update to `libp2p-core` `v0.39.0`.

- Update to `libp2p-dcutr` `v0.9.0`.

- Update to `libp2p-ping` `v0.42.0`.
Expand All @@ -19,6 +21,7 @@
- Update to `libp2p-swarm` `v0.42.0`.

[PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134/
[PR 3207]: https://github.com/libp2p/rust-libp2p/pull/3207/

# 0.11.0

Expand Down
4 changes: 2 additions & 2 deletions misc/metrics/Cargo.toml
Expand Up @@ -26,7 +26,7 @@ libp2p-kad = { version = "0.43.0", path = "../../protocols/kad", optional = true
libp2p-ping = { version = "0.42.0", path = "../../protocols/ping", optional = true }
libp2p-relay = { version = "0.15.0", path = "../../protocols/relay", optional = true }
libp2p-swarm = { version = "0.42.0", path = "../../swarm" }
prometheus-client = "0.18.0"
prometheus-client = "0.19.0"

[target.'cfg(not(target_os = "unknown"))'.dependencies]
libp2p-gossipsub = { version = "0.44.0", path = "../../protocols/gossipsub", optional = true }
Expand All @@ -52,4 +52,4 @@ rustc-args = ["--cfg", "docsrs"]

[[example]]
name = "metrics"
required-features = ["ping"]
required-features = ["ping", "identify"]
30 changes: 18 additions & 12 deletions misc/metrics/examples/metrics/http_service.rs
Expand Up @@ -29,6 +29,8 @@ use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll};

const METRICS_CONTENT_TYPE: &str = "application/openmetrics-text;charset=utf-8;version=1.0.0";

pub async fn metrics_server(registry: Registry) -> Result<(), std::io::Error> {
// Serve on localhost.
let addr = ([127, 0, 0, 1], 0).into();
Expand All @@ -55,27 +57,31 @@ impl MetricService {
fn get_reg(&mut self) -> SharedRegistry {
Arc::clone(&self.reg)
}
fn respond_with_metrics(&mut self) -> Response<Body> {
let mut encoded: Vec<u8> = Vec::new();
fn respond_with_metrics(&mut self) -> Response<String> {
let mut response: Response<String> = Response::default();

response.headers_mut().insert(
hyper::header::CONTENT_TYPE,
METRICS_CONTENT_TYPE.try_into().unwrap(),
);

let reg = self.get_reg();
encode(&mut encoded, &reg.lock().unwrap()).unwrap();
let metrics_content_type = "application/openmetrics-text;charset=utf-8;version=1.0.0";
Response::builder()
.status(StatusCode::OK)
.header(hyper::header::CONTENT_TYPE, metrics_content_type)
.body(Body::from(encoded))
.unwrap()
encode(&mut response.body_mut(), &reg.lock().unwrap()).unwrap();

*response.status_mut() = StatusCode::OK;

response
}
fn respond_with_404_not_found(&mut self) -> Response<Body> {
fn respond_with_404_not_found(&mut self) -> Response<String> {
Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("Not found try localhost:[port]/metrics"))
.body("Not found try localhost:[port]/metrics".to_string())
.unwrap()
}
}

impl Service<Request<Body>> for MetricService {
type Response = Response<Body>;
type Response = Response<String>;
type Error = hyper::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

Expand Down
8 changes: 4 additions & 4 deletions misc/metrics/src/dcutr.rs
Expand Up @@ -18,7 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use prometheus_client::encoding::text::Encode;
use prometheus_client::encoding::{EncodeLabelSet, EncodeLabelValue};
use prometheus_client::metrics::counter::Counter;
use prometheus_client::metrics::family::Family;
use prometheus_client::registry::Registry;
Expand All @@ -35,19 +35,19 @@ impl Metrics {
sub_registry.register(
"events",
"Events emitted by the relay NetworkBehaviour",
Box::new(events.clone()),
events.clone(),
);

Self { events }
}
}

#[derive(Debug, Clone, Hash, PartialEq, Eq, Encode)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, EncodeLabelSet)]
struct EventLabels {
event: EventType,
}

#[derive(Debug, Clone, Hash, PartialEq, Eq, Encode)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, EncodeLabelValue)]
enum EventType {
InitiateDirectConnectionUpgrade,
RemoteInitiatedDirectConnectionUpgrade,
Expand Down
6 changes: 1 addition & 5 deletions misc/metrics/src/gossipsub.rs
Expand Up @@ -30,11 +30,7 @@ impl Metrics {
let sub_registry = registry.sub_registry_with_prefix("gossipsub");

let messages = Counter::default();
sub_registry.register(
"messages",
"Number of messages received",
Box::new(messages.clone()),
);
sub_registry.register("messages", "Number of messages received", messages.clone());

Self { messages }
}
Expand Down
33 changes: 15 additions & 18 deletions misc/metrics/src/identify.rs
Expand Up @@ -20,7 +20,7 @@

use crate::protocol_stack;
use libp2p_core::PeerId;
use prometheus_client::encoding::text::{Encode, EncodeMetric, Encoder};
use prometheus_client::encoding::{EncodeLabelSet, EncodeMetric, MetricEncoder};
use prometheus_client::metrics::counter::Counter;
use prometheus_client::metrics::family::Family;
use prometheus_client::metrics::histogram::{exponential_buckets, Histogram};
Expand Down Expand Up @@ -51,30 +51,30 @@ impl Metrics {
"Number of connected nodes supporting a specific protocol, with \
\"unrecognized\" for each peer supporting one or more unrecognized \
protocols",
Box::new(protocols.clone()),
protocols.clone(),
);

let error = Counter::default();
sub_registry.register(
"errors",
"Number of errors while attempting to identify the remote",
Box::new(error.clone()),
error.clone(),
);

let pushed = Counter::default();
sub_registry.register(
"pushed",
"Number of times identification information of the local node has \
been actively pushed to a peer.",
Box::new(pushed.clone()),
pushed.clone(),
);

let received = Counter::default();
sub_registry.register(
"received",
"Number of times identification information has been received from \
a peer",
Box::new(received.clone()),
received.clone(),
);

let received_info_listen_addrs =
Expand All @@ -83,7 +83,7 @@ impl Metrics {
"received_info_listen_addrs",
"Number of listen addresses for remote peer received in \
identification information",
Box::new(received_info_listen_addrs.clone()),
received_info_listen_addrs.clone(),
);

let received_info_protocols =
Expand All @@ -92,22 +92,22 @@ impl Metrics {
"received_info_protocols",
"Number of protocols supported by the remote peer received in \
identification information",
Box::new(received_info_protocols.clone()),
received_info_protocols.clone(),
);

let sent = Counter::default();
sub_registry.register(
"sent",
"Number of times identification information of the local node has \
been sent to a peer in response to an identification request",
Box::new(sent.clone()),
sent.clone(),
);

let listen_addresses = Family::default();
sub_registry.register(
"listen_addresses",
"Number of listen addresses for remote peer per protocol stack",
Box::new(listen_addresses.clone()),
listen_addresses.clone(),
);

Self {
Expand Down Expand Up @@ -208,12 +208,12 @@ impl<TBvEv, THandleErr> super::Recorder<libp2p_swarm::SwarmEvent<TBvEv, THandleE
}
}

#[derive(Encode, Hash, Clone, Eq, PartialEq)]
#[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)]
struct AddressLabels {
protocols: String,
}

#[derive(Default, Clone)]
#[derive(Default, Clone, Debug)]
struct Protocols {
peers: Arc<Mutex<HashMap<PeerId, Vec<String>>>>,
}
Expand All @@ -235,14 +235,14 @@ impl Protocols {
}

impl EncodeMetric for Protocols {
fn encode(&self, mut encoder: Encoder) -> Result<(), std::io::Error> {
fn encode(&self, mut encoder: MetricEncoder) -> Result<(), std::fmt::Error> {
let count_by_protocol = self
.peers
.lock()
.expect("Lock not to be poisoned")
.iter()
.fold(
HashMap::<String, u64>::default(),
HashMap::<String, i64>::default(),
|mut acc, (_, protocols)| {
for protocol in protocols {
let count = acc.entry(protocol.to_string()).or_default();
Expand All @@ -254,11 +254,8 @@ impl EncodeMetric for Protocols {

for (protocol, count) in count_by_protocol {
encoder
.with_label_set(&("protocol", protocol))
.no_suffix()?
.no_bucket()?
.encode_value(count)?
.no_exemplar()?;
.encode_family(&[("protocol", protocol)])?
.encode_gauge(&count)?;
}

Ok(())
Expand Down