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

misc/metrics: Add protocols label to address-specific metrics #2982

Merged
merged 27 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d7c0f89
Getting started
John-LittleBearLabs Oct 4, 2022
3345407
Merge remote-tracking branch 'jt/master' into addrstak_metric
John-LittleBearLabs Oct 4, 2022
32d5eb0
Merge remote-tracking branch 'origin/master' into addrstak_metric
John-LittleBearLabs Oct 7, 2022
d815970
Post merge fixup and re-check.
John-LittleBearLabs Oct 7, 2022
14e906a
Pulling protocol_stack functionality into this repo, by request.
John-LittleBearLabs Oct 11, 2022
808c439
A couple of suggestions from PR
John-LittleBearLabs Oct 13, 2022
4842a64
Merge remote-tracking branch 'origin/master' into addrstak_metric
John-LittleBearLabs Oct 13, 2022
9c6b300
Label wrapper
John-LittleBearLabs Oct 14, 2022
f165e01
MultiaddrExt
John-LittleBearLabs Oct 14, 2022
b2c74ed
not From
John-LittleBearLabs Oct 14, 2022
50c8bb5
cargo fmt
John-LittleBearLabs Oct 14, 2022
d74e7e5
clippy
John-LittleBearLabs Oct 14, 2022
e5974ca
changelog
John-LittleBearLabs Oct 14, 2022
1d13413
Merge remote-tracking branch 'origin/master' into addrstak_metric
John-LittleBearLabs Oct 17, 2022
3900f69
Version bump.
John-LittleBearLabs Oct 17, 2022
9a227ca
PR comment
John-LittleBearLabs Oct 19, 2022
b618cf8
Merge remote-tracking branch 'origin/master' into addrstak_metric
John-LittleBearLabs Nov 2, 2022
16c802b
A couple PR comments.
John-LittleBearLabs Nov 2, 2022
6a5a593
Use protocol stack for a few more metrics.
John-LittleBearLabs Nov 3, 2022
6983a59
metric label naming consistency
John-LittleBearLabs Nov 4, 2022
c8bcc82
remove impl From
John-LittleBearLabs Nov 4, 2022
ece8c9b
PR comments & clippy
John-LittleBearLabs Nov 8, 2022
db1bcdc
Merge from master, update protocol_stack to use upstream. Should have…
John-LittleBearLabs Nov 14, 2022
0f6bdd1
Fix a clippy and a no-default-feature use stmt
John-LittleBearLabs Nov 14, 2022
f787368
Move `Labels` to usage site
thomaseizinger Nov 15, 2022
0d3ec5b
Merge branch 'master' into addrstak_metric
mergify[bot] Nov 15, 2022
7176f14
Merge branch 'master' into addrstak_metric
thomaseizinger Nov 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions misc/metrics/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

- Update to `libp2p-gossipsub` `v0.43.0`.

- Add `protocol_stack` metrics. See [PR 2982].

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

# 0.10.0

- Update to `libp2p-swarm` `v0.40.0`.
Expand Down
25 changes: 22 additions & 3 deletions misc/metrics/examples/metrics/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use futures::stream::StreamExt;
use libp2p::core::Multiaddr;
use libp2p::metrics::{Metrics, Recorder};
use libp2p::swarm::{NetworkBehaviour, SwarmEvent};
use libp2p::{identity, ping, PeerId, Swarm};
use libp2p::{identify, identity, ping, PeerId, Swarm};
use libp2p_swarm::keep_alive;
use log::info;
use prometheus_client::registry::Registry;
Expand All @@ -68,11 +68,12 @@ fn main() -> Result<(), Box<dyn Error>> {

let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());
let local_pub_key = local_key.public();
info!("Local peer id: {:?}", local_peer_id);

let mut swarm = Swarm::without_executor(
block_on(libp2p::development_transport(local_key))?,
Behaviour::default(),
Behaviour::new(local_pub_key),
local_peer_id,
);

Expand All @@ -95,6 +96,10 @@ fn main() -> Result<(), Box<dyn Error>> {
info!("{:?}", ping_event);
metrics.record(&ping_event);
}
SwarmEvent::Behaviour(BehaviourEvent::Identify(identify_event)) => {
info!("{:?}", identify_event);
metrics.record(&identify_event);
}
swarm_event => {
info!("{:?}", swarm_event);
metrics.record(&swarm_event);
Expand All @@ -109,8 +114,22 @@ fn main() -> Result<(), Box<dyn Error>> {
///
/// For illustrative purposes, this includes the [`keep_alive::Behaviour`]) behaviour so the ping actually happen
/// and can be observed via the metrics.
#[derive(NetworkBehaviour, Default)]
#[derive(NetworkBehaviour)]
struct Behaviour {
identify: identify::Behaviour,
keep_alive: keep_alive::Behaviour,
ping: ping::Behaviour,
}

impl Behaviour {
fn new(local_pub_key: libp2p::identity::PublicKey) -> Self {
Self {
ping: ping::Behaviour::default(),
identify: identify::Behaviour::new(identify::Config::new(
"/ipfs/0.1.0".into(),
local_pub_key,
)),
keep_alive: keep_alive::Behaviour::default(),
}
}
}
25 changes: 24 additions & 1 deletion misc/metrics/src/identify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use crate::protocol_stack;
use libp2p_core::PeerId;
use prometheus_client::encoding::text::{EncodeMetric, Encoder};
use prometheus_client::encoding::text::{Encode, EncodeMetric, Encoder};
use prometheus_client::metrics::counter::Counter;
use prometheus_client::metrics::family::Family;
use prometheus_client::metrics::histogram::{exponential_buckets, Histogram};
use prometheus_client::metrics::MetricType;
use prometheus_client::registry::Registry;
Expand All @@ -36,6 +38,7 @@ pub struct Metrics {
received_info_listen_addrs: Histogram,
received_info_protocols: Histogram,
sent: Counter,
listen_addresses: Family<AddressLabels, Counter>,
}

impl Metrics {
Expand Down Expand Up @@ -100,6 +103,13 @@ impl Metrics {
Box::new(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()),
);

Self {
protocols,
error,
Expand All @@ -108,6 +118,7 @@ impl Metrics {
received_info_listen_addrs,
received_info_protocols,
sent,
listen_addresses,
}
}
}
Expand Down Expand Up @@ -167,6 +178,13 @@ impl super::Recorder<libp2p_identify::Event> for Metrics {
.observe(info.protocols.len() as f64);
self.received_info_listen_addrs
.observe(info.listen_addrs.len() as f64);
for listen_addr in &info.listen_addrs {
self.listen_addresses
.get_or_create(&AddressLabels {
protocols: protocol_stack::as_string(listen_addr),
})
.inc();
}
}
libp2p_identify::Event::Sent { .. } => {
self.sent.inc();
Expand All @@ -190,6 +208,11 @@ impl<TBvEv, THandleErr> super::Recorder<libp2p_swarm::SwarmEvent<TBvEv, THandleE
}
}

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

#[derive(Default, Clone)]
struct Protocols {
peers: Arc<Mutex<HashMap<PeerId, Vec<String>>>>,
Expand Down
1 change: 1 addition & 0 deletions misc/metrics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mod identify;
mod kad;
#[cfg(feature = "ping")]
mod ping;
mod protocol_stack;
#[cfg(feature = "relay")]
mod relay;
mod swarm;
Expand Down
27 changes: 27 additions & 0 deletions misc/metrics/src/protocol_stack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use libp2p_core::multiaddr::Multiaddr;

pub fn as_string(ma: &Multiaddr) -> String {
let len = ma
.protocol_stack()
.fold(0, |acc, proto| acc + proto.len() + 1);
let mut protocols = String::with_capacity(len);
for proto_tag in ma.protocol_stack() {
protocols.push('/');
protocols.push_str(proto_tag);
}
protocols
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn ip6_tcp_wss_p2p() {
let ma = Multiaddr::try_from("/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/wss/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC").expect("testbad");

let protocol_stack = as_string(&ma);

assert_eq!(protocol_stack, "/ip6/tcp/wss/p2p");
}
}
82 changes: 60 additions & 22 deletions misc/metrics/src/swarm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,38 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use crate::protocol_stack;
use prometheus_client::encoding::text::Encode;
use prometheus_client::metrics::counter::Counter;
use prometheus_client::metrics::family::Family;
use prometheus_client::registry::Registry;

pub struct Metrics {
connections_incoming: Counter,
connections_incoming: Family<AddressLabels, Counter>,
connections_incoming_error: Family<IncomingConnectionErrorLabels, Counter>,

connections_established: Family<ConnectionEstablishedLabels, Counter>,
connections_closed: Family<ConnectionClosedLabels, Counter>,

new_listen_addr: Counter,
expired_listen_addr: Counter,
new_listen_addr: Family<AddressLabels, Counter>,
expired_listen_addr: Family<AddressLabels, Counter>,

listener_closed: Counter,
listener_closed: Family<AddressLabels, Counter>,
listener_error: Counter,

dial_attempt: Counter,
outgoing_connection_error: Family<OutgoingConnectionErrorLabels, Counter>,
connected_to_banned_peer: Counter,
connected_to_banned_peer: Family<AddressLabels, Counter>,
}

impl Metrics {
pub fn new(registry: &mut Registry) -> Self {
let sub_registry = registry.sub_registry_with_prefix("swarm");

let connections_incoming = Counter::default();
let connections_incoming = Family::default();
sub_registry.register(
"connections_incoming",
"Number of incoming connections",
"Number of incoming connections per address stack",
Box::new(connections_incoming.clone()),
);

Expand All @@ -59,21 +60,21 @@ impl Metrics {
Box::new(connections_incoming_error.clone()),
);

let new_listen_addr = Counter::default();
let new_listen_addr = Family::default();
sub_registry.register(
"new_listen_addr",
"Number of new listen addresses",
Box::new(new_listen_addr.clone()),
);

let expired_listen_addr = Counter::default();
let expired_listen_addr = Family::default();
sub_registry.register(
"expired_listen_addr",
"Number of expired listen addresses",
Box::new(expired_listen_addr.clone()),
);

let listener_closed = Counter::default();
let listener_closed = Family::default();
sub_registry.register(
"listener_closed",
"Number of listeners closed",
Expand Down Expand Up @@ -101,7 +102,7 @@ impl Metrics {
Box::new(outgoing_connection_error.clone()),
);

let connected_to_banned_peer = Counter::default();
let connected_to_banned_peer = Family::default();
sub_registry.register(
"connected_to_banned_peer",
"Number of connection attempts to banned peer",
Expand Down Expand Up @@ -146,23 +147,34 @@ impl<TBvEv, THandleErr> super::Recorder<libp2p_swarm::SwarmEvent<TBvEv, THandleE
self.connections_established
.get_or_create(&ConnectionEstablishedLabels {
role: endpoint.into(),
protocols: protocol_stack::as_string(endpoint.get_remote_address()),
})
.inc();
}
libp2p_swarm::SwarmEvent::ConnectionClosed { endpoint, .. } => {
self.connections_closed
.get_or_create(&ConnectionClosedLabels {
role: endpoint.into(),
protocols: protocol_stack::as_string(endpoint.get_remote_address()),
})
.inc();
}
libp2p_swarm::SwarmEvent::IncomingConnection { .. } => {
self.connections_incoming.inc();
libp2p_swarm::SwarmEvent::IncomingConnection { send_back_addr, .. } => {
thomaseizinger marked this conversation as resolved.
Show resolved Hide resolved
self.connections_incoming
.get_or_create(&AddressLabels {
protocols: protocol_stack::as_string(send_back_addr),
})
.inc();
}
libp2p_swarm::SwarmEvent::IncomingConnectionError { error, .. } => {
libp2p_swarm::SwarmEvent::IncomingConnectionError {
error,
send_back_addr,
..
} => {
self.connections_incoming_error
.get_or_create(&IncomingConnectionErrorLabels {
error: error.into(),
protocols: protocol_stack::as_string(send_back_addr),
})
.inc();
}
Expand Down Expand Up @@ -221,17 +233,35 @@ impl<TBvEv, THandleErr> super::Recorder<libp2p_swarm::SwarmEvent<TBvEv, THandleE
}
};
}
libp2p_swarm::SwarmEvent::BannedPeer { .. } => {
self.connected_to_banned_peer.inc();
libp2p_swarm::SwarmEvent::BannedPeer { endpoint, .. } => {
self.connected_to_banned_peer
.get_or_create(&AddressLabels {
protocols: protocol_stack::as_string(endpoint.get_remote_address()),
})
.inc();
}
libp2p_swarm::SwarmEvent::NewListenAddr { .. } => {
self.new_listen_addr.inc();
libp2p_swarm::SwarmEvent::NewListenAddr { address, .. } => {
self.new_listen_addr
.get_or_create(&AddressLabels {
protocols: protocol_stack::as_string(address),
})
.inc();
}
libp2p_swarm::SwarmEvent::ExpiredListenAddr { .. } => {
self.expired_listen_addr.inc();
libp2p_swarm::SwarmEvent::ExpiredListenAddr { address, .. } => {
self.expired_listen_addr
.get_or_create(&AddressLabels {
protocols: protocol_stack::as_string(address),
})
.inc();
}
libp2p_swarm::SwarmEvent::ListenerClosed { .. } => {
self.listener_closed.inc();
libp2p_swarm::SwarmEvent::ListenerClosed { addresses, .. } => {
for address in addresses {
self.listener_closed
.get_or_create(&AddressLabels {
protocols: protocol_stack::as_string(address),
})
.inc();
}
}
libp2p_swarm::SwarmEvent::ListenerError { .. } => {
self.listener_error.inc();
Expand All @@ -246,11 +276,18 @@ impl<TBvEv, THandleErr> super::Recorder<libp2p_swarm::SwarmEvent<TBvEv, THandleE
#[derive(Encode, Hash, Clone, Eq, PartialEq)]
struct ConnectionEstablishedLabels {
role: Role,
protocols: String,
}

#[derive(Encode, Hash, Clone, Eq, PartialEq)]
struct ConnectionClosedLabels {
role: Role,
protocols: String,
}

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

#[derive(Encode, Hash, Clone, Eq, PartialEq)]
Expand Down Expand Up @@ -298,6 +335,7 @@ enum OutgoingConnectionErrorError {
#[derive(Encode, Hash, Clone, Eq, PartialEq)]
struct IncomingConnectionErrorLabels {
error: PendingInboundConnectionError,
protocols: String,
}

#[derive(Encode, Hash, Clone, Eq, PartialEq)]
Expand Down